列表:计数与计数()
给定一个列表,哪个方法首选确定里面的元素个数?
var myList = new List<string>(); myList.Count myList.Count()
Count()
是LINQ引入的扩展方法,而Count
属性是List自身的一部分(从ICollection
派生)。 但是,在内部,LINQ检查你的IEnumerable
实现了ICollection
,如果是,它使用Count
属性。 所以在这一天结束的时候,你用List
没有什么区别。
为了进一步certificate我的观点,下面是来自Reflector for Enumerable.Count()
的代码
public static int Count<TSource>(this IEnumerable<TSource> source) { if (source == null) { throw Error.ArgumentNull("source"); } ICollection<TSource> is2 = source as ICollection<TSource>; if (is2 != null) { return is2.Count; } int num = 0; using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; }
总是在扩展方法Count()
上使用Count
和Length
属性。 前者是包含它们的每种types的一个O(1)。 Count()
扩展方法有一些types检查优化,可能导致它在O(1)时间内运行,但是如果底层集合不是它知道的几个types之一,则会降级到O(N)。
myList.Count是列表对象上的一个方法,它只是返回一个字段的值,所以非常快。 由于这是一个很小的方法,它很可能被编译器(或运行时)内联,因此它们可能允许编译器进行其他优化。
myList.Count()正在调用一个扩展方法(由LINQ引入),它循环遍历IEnumerabl中的所有项目,因此应该慢很多。
但是(在Microsoft实现中),Count扩展方法对列表有一个“特例”,允许它使用列表的Count属性,这意味着Count()方法只比Count属性慢一点。
在大多数应用中,你几乎不可能分辨速度的差异。
所以,如果你知道你正在处理一个列表使用计数属性,否则,如果你有一个“未知的”IEnumerabl,使用Count()方法,让它为你优化。
如果你有任何机会想改变你的collectionstypes,最好用Count()
扩展。 这样你不必重构你的代码(例如使用Length
)。