Robust Software

Tales of a code samurai

Beware Count()

Something I’ve seen at various times is:

1
2
3
4
if (enumerable.Count() > 0)
{
    ... do stuff ...
}

I’ve always preferred using:

1
2
3
4
if (enumerable.Any())
{
    ... do stuff ...
}

Mostly because it reads better, but partly because I felt it was bound to be more efficient. I’m not sure if I actually confirmed that before but after seeing one today I checked on it.

This is the implementation of Count():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static int Count(this IEnumerable<T> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<T> is2 = source as ICollection<T>;
    if (is2 != null)
    {
        return is2.Count;
    }
    int num = 0;
    using (IEnumerator<T> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}

You can see there is a special case for implementors of ICollection<T> so it uses the Count property (which you should use anyway instead of the extension method if it is available). However, if it is truly an IEnumerable<T> it will iterate over the whole collection incrementing an int as it goes. That’s not very efficient if your only checking if there is anything in there or not.

Here’s the implementation of Any():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static bool Any(this IEnumerable<T> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<T> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}

Gets the enumerator and sees if it can retrieve an item from it. Much more efficient.

Here’s a rule of thumb for checking if a collection has anything in it:

  1. Use the Count property if it’s available as it is cached and does not need to instantiate an enumerator at all
  2. Use the Any() extension method otherwise