Tech Quiz: Some micro optimization

2012-06-16

Optimize the following code:


doubletotalCount = 0;  

for (int index = 0; index < numberOfRuns; index++)
{
    string[] values = GetData(index);
    totalCount += values.Count();
}

Answer

A simple optimization is to replace Count() with Length.

Count() is an extension method that looks something like this:

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;  
    }
    ICollection is3 = source as  ICollection; if (is3 != null)  
    {
        return is3.Count;  
    }
    int num = 0;  
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())  
    {
        while(enumerator.MoveNext())  
        {  
            num++;  
        }  
    }
    return num;  
}

If an IEnumerable can be cast to a ICollection or ICollection, the extension method will use the Count property. If that’s not possible, it will enumerate all the elements and count the total.

The string array can be cast to a ICollection so it can use the shortcut by using the Count property. However, the Lenght property of the array accesses this directly and avoids the cast.

What’s more important to realize is, that if your collection does not implement ICollection, Count() will have to enumerate all the elements to count the total which can be a huge performance hit.