Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count method or property for an IList

Tags:

c#

Thanks for help with explaining to me about IList and IEnumerable. I have marked that question as answered. Now I have a request for just a bit more information.

I have code like this:

for (var index = 0; index < Model.Items.Count(); index++) 

It was suggested in a previous post that it's not efficient as the Count() is a method and it gets executed many times. I tried the following:

for (var index = 0; index < Model.Items.Count; index++) 

This seems to work.

Can someone please confirm there's a difference. Both work so I am not 100 % sure.

Would the following be the most efficient? Does the foreach need an IList or and IEnumerable?

foreach(var item in Items) 
like image 912
Samantha J T Star Avatar asked Jan 01 '12 11:01

Samantha J T Star


2 Answers

Count() extension method works for all objects that support IEnumerable, and since IEnumerable itself does not have any means of reporting item count, it may have to iterate over IEnumerable instance using it's IEnumerator, which can be a real performance hit if called many times.

However, if you look into Count() implementation, you'll see that it is optimized for ICollection types (both generic and non-generic, at least in FW4.0, meaning IList and IList<T> are also optimized), and if your object implements ICollection (which reports item count in Count property), Count() method returns item count without iterating through collection. That's why you don't see performance difference. Nevertheless, if you know that you have ICollection or IList instance, why not get Count property directly and be independent of Count() method implementation?

Also, remember that you can cache return value of Count() method in a variable to suppress multiple calls:

var count = Model.Items.Count();
for(var index = 0; index < count; index++) { }
like image 87
max Avatar answered Sep 30 '22 12:09

max


The Count() method call actually calls the static Enumerable.Count() method. This is optimized for IList implementations to use the property - but this requires a dynamic type check, and still ends up going through to the property - so using the property is certainly more efficient. In .NET 3.5 it only optimizes for ICollection<T>, whereas in .NET 4 it optimizes for the non-generic ICollection as well. See my Edulinq blog post on Count for more details.

As for the last bit of your question: a foreach loop may or may not be more efficient, but it would be more readable in my view, which is rather more important. I would definitely use foreach unless you really need the index of each entry.

like image 40
Jon Skeet Avatar answered Sep 30 '22 11:09

Jon Skeet