Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In IEnumerable extensions - why is only Count() optimized for ICollection?

After de-compiling the Linq IEnumerable extension methods I was glad to see that
the Count() method, prior to trying to iterate the whole enumerable, attempts to downcast it to an ICollection or an ICollection<T> e.g:

    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;
    }

Why isn't this happening in Any()? won't it benefit from using .Count > 0 instead of creating an array enumerator?

like image 416
Nitzan Avatar asked Oct 07 '14 13:10

Nitzan


People also ask

Does IEnumerable have count?

IEnumerable doesn't have a Count method.

Is count faster than any?

Any() is ALWAYS faster than . Count() > 0 ).

Should I use ICollection or IEnumerable?

IEnumerable contains only GetEnumerator() method, like read-only iterate. ICollection is one step ahead of IEnumerable. If we want some more functionality like Add or remove element, then it is better to go with ICollection because we cannot achieve that with IEnumerable. ICollection extends IEnumerable.

What is IEnumerable and what significance does it hold?

What is IEnumerable in C#? IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.


1 Answers

Not all collections provide O(1) access for Count property. For example accessing count property of ConcurrentQueue<T> is O(n). So that optimization will make it worse and hence shouldn't be called as optimization.

Not only ConcurrentQueue<T>, Almost all concurrent collections (ConcurrentDictionary<TKey,TValue>, ConcurrentStack<T> etc) falls in this category

May be that is why they decided not to do it.

like image 125
Sriram Sakthivel Avatar answered Oct 26 '22 19:10

Sriram Sakthivel