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)
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++) { }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With