Reputation: 7516
List<string> list = new List<string>() {"a", "b", "c"};
IEnumerable<string> enumerable = list;
int c1 = list.Count;
int c2 = list.Count();
int c3 = enumerable.Count();
Are there differences in performance and implementation between these last 3 statements? Will list.Count()
perform worse or the same as list.Count
, and does it matter if the reference is of type IEnumerable<string>
?
Upvotes: 7
Views: 1768
Reputation: 55996
Let's look with Reflector:
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;
}
So, if your IEnumerable<T>
implements ICollection<T>
or ICollection
, it will return the Count
property.
Upvotes: 10
Reputation: 60714
The implementation of the count on IEnumerable
first checks if the enumerable list also implements ICollection<T>
where T is the generic parameter of the enumerable list.
If it does, it returns ICollection<T>.Count
.
If not, it checks if it implements ICollection
. If it does it returns ICollection.Count
.
If it does not implement neither of those it has to iterate through the entire list and count, and this might be a expensive operation for a big list.
List<string>
however implements ICollection<string>
and therefore the performance will be the same.
Upvotes: 1
Reputation: 30883
The Linq Count method is clever enough not to iterate over the underlying collection if it implements ICollection interface and therefore already has Count property.
Upvotes: 3
Reputation: 75629
I assume it works like this: a List keeps its own count in a variable. Count() loops through the IEnumerable to count the number of elements. That would make List.Count more efficient.
Upvotes: 0