[C#]Linq 计数 vs IList 计数

标签: Linq C#
发布时间: 2017/2/27 4:04:22
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

如果我有下面的 IEnumerable 列表来自一些存储库。

IEnumerable<SomeObject> items = _someRepo.GetAll();

什么是更快︰

items.Count(); // Using Linq on the IEnumerable interface.

List<SomeObject> temp = items.ToList<SomeObject>(); // Cast as a List

temp.Count(); // Do a count on a list

Linq Count() 更快或更慢比铸造 IEnumerableList ,然后执行 Count() 吗?

更新︰ 改善问题稍微有点更现实的场景。

解决方法 1:

调用 Count 直接是一个更好的选择。

Enumerable.Count有一些建的改进,会让它返回而不枚举整个集合的性能︰

public static int Count<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) return collectionoft.Count;
    ICollection collection = source as ICollection;
    if (collection != null) return collection.Count;
    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        checked {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}

ToList()采用类似的优化,烤成 List<T>(IEnumerable<T> source) 构造函数︰

public List(IEnumerable<T> collection) {
    if (collection==null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
    Contract.EndContractBlock();

    ICollection<T> c = collection as ICollection<T>;
    if( c != null) {
        int count = c.Count;
        if (count == 0)
        {
            _items = _emptyArray;
        }
        else {
            _items = new T[count];
            c.CopyTo(_items, 0);
            _size = count;
        }
    }    
    else {                
        _size = 0;
        _items = _emptyArray;
        // This enumerable could be empty.  Let Add allocate a new array, if needed.
        // Note it will also go to _defaultCapacity first, not 1, then 2, etc.

        using(IEnumerator<T> en = collection.GetEnumerator()) {
            while(en.MoveNext()) {
                Add(en.Current);                                    
            }
        }
    }
}

但正如你可以看到它只使用泛型 ICollection<T> ,所以如果你集合实现 ICollection 但不是其泛型版本电话 Count() 直接会快得多。

不调用 ToList 第一次还可以节省你分配的新 List<T> 实例-不是过于昂贵,但也总是更好,避免不必要的分配,在可能的情况。

官方微信
官方QQ群
31647020