13

Is there any speed improvement or indeed point in checking the Count() of an Enumerable before iterating/foreaching over the collection?

List<int> numbers = new List<int>();

if(numbers.Count() > 0)
{
    foreach(var i in numbers) {/*Do something*/}
}
Bridge
  • 29,818
  • 9
  • 60
  • 82
Paul C
  • 4,687
  • 5
  • 39
  • 55

5 Answers5

26

No, the opposite can be true. If it's not a collection (like a List or Array) but a deferred executed query it must be executed completely which can be very expensive, just to determine the count. In your example it's actually a List, Enumerable.Count is clever enough to try to cast it to a ICollection<T>/ICollection first . If that succeeds the Count property is used.

So just use the foreach. It doesn't hurt if the sequence is empty, the loop will be exited immediately.

For the same reason it's better to use Enumerable.Any instead of Count() > 0 if you just want to check if a sequence contains at least one element. The intention is also more clear.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • So although it's a side-note to make your answer complete for anyone reading this, the only check you MUST do, is to check for `null` if there is any possibility the collection could be. Obviously in my example it can't be. – Paul C Jan 08 '14 at 08:55
  • 1
    @CodeBlend: the `null` check should be done first, if it's a parameter in the method you should throw a `ArgumentNullException` with a meaningful message. – Tim Schmelter Jan 08 '14 at 08:58
  • But regarding [This](https://stackoverflow.com/questions/305092/which-method-performs-better-any-vs-count-0) it's better to use .Count on `ICollection`, `IList`, `List`, where on `IEnumerable` its better to use .Any() when you want to check if a sequence contains at least one element. – Hantick Oct 25 '22 at 11:54
  • @Hantick: it's micro-optimization if the type is really a collection since they are implemented in a way that `Any` is almost the same as using the `Count`/`Length` property. If it's not a collection `Any` must be used and it can cause big troubles if you use `Count()` instead. – Tim Schmelter Oct 25 '22 at 15:29
2

If your Enumarable is lazy evaluated (LINQ) the call to Count() is actually very bad since it evaluates the whole Enumerable.

Since foreach doesn't execute if the Enumarable is empty it's best to not use Count.

Martin Walter
  • 540
  • 5
  • 11
1

I don't believe there is any speed improvement or indeed point in checking the Count() of an Enumerable before iterating/foreaching over the collection. As no code is executed within the foreach block if there isn't any items in the collection anyway.

Paul C
  • 4,687
  • 5
  • 39
  • 55
  • I agree. `foreach` is safe, in the sense that it simply iterates 0 times if the enumerable is empty, so no checking is needed beforehand (unless the enumerable can be `NULL` of course!) – oerkelens Jan 08 '14 at 08:49
1

Even if you want to check for the count, use Count instead of the extension method Count() since the performance of Count() is worse then Count

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 1
    Probably the performance loss is less then a lot, but it is bad design, and it probably means some kind of reflection on the object and also the CLR has to go up the stack for it, so it does always impact performance. – Patrick Hofman Jan 08 '14 at 10:29
  • @CodeBlend: whoops, i have deleted my comment before you've posted yours. It's not incorrect since `Count` is more efficient than `Count()`, but in case of collections the `Count` property is used even if you use `Enumerable.Count`. But since an additional method must be invoked which t cast it to `Collection`, the direct use of `Count` is more efficient, but that's really micro-optimization. I would prefer `Enumerable.Count` since it allows to change the type (e.g. to array or `IEnumerable`). Sometimes it's better to "hide" the real type and declare the base type f.e. to prevent mutation. – Tim Schmelter Jan 08 '14 at 10:36
1

Short answer: No, on the contrary.
Longer answer: The foreach keyword calls methods on the IEnumerator interface. These methods implicitly check for items being present. So calling Count() is purely redundant.

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34