7

when using a foreach loop in Unity I need to call this in the update method. So it's called once per frame...

I want to know, if it is better to check the count of the list before using the foreach loop or if it is redundant.

So I have

if (myList.Count > 0)
{
    foreach (Type type in myList)
    {
    }
}

and

foreach (Type type in myList) // no need for a check before
{
}

I could also use

for (int i = 0; i < myList.Count; i++) // use a for loop instead
{
    myList[i].DoSomething();
}
Question3r
  • 2,166
  • 19
  • 100
  • 200
  • 1
    Read this first: https://ericlippert.com/2012/12/17/performance-rant/ – DavidG Aug 12 '17 at 14:25
  • did you try for loop? for performace better than foreach. https://stackoverflow.com/a/365658/4662054 – OsmanSenol Aug 12 '17 at 14:26
  • 4
    No need for the check. Do not get caught up in things like these. If your program is running slowly, it isn't going to be sped up by checking if a list is empty before attempting to iterate over it. "Premature optimization is the root of all evil." - Donald Knuth. – Captain Skyhawk Aug 12 '17 at 14:32
  • 3
    @OsmanSenol: I would definitely recommend against assuming that performance characteristic that may have been true 9 years ago are still true. (Especially as the blog post that the answer refers to no longer exists - at least not at that URL.) – Jon Skeet Aug 12 '17 at 14:36
  • As you know property is a two method: get/set. So when you retrive `List.Count` you invoke a method. It means that processor puts some values on the stack, remembers the curent position for returning and etc. In the other hand, `foreach` retrive bool value from `IEnumerator.MoveNext()` so you also invoke a method, processor puts values on the stack and etc. So as you see this two ways spent the same time and one of them can be better if a JIT or a a processor do some tiny optimization. – George Alexandria Aug 12 '17 at 14:40
  • So I updated my question. Should I use the foreach loop or the for loop now? Yes, I know, the for loop is faster. – Question3r Aug 12 '17 at 14:45
  • If you know that the `for` is faster and you use `IList` that has indexer why you ask this question? – George Alexandria Aug 12 '17 at 14:46
  • @JonSkeet sorry about old post and thank you for your advice. but i know that still for loop is faster than foreach loop and foreach generates garbage. let me add newer post http://www.theappguruz.com/blog/foreach-loop-optimization – OsmanSenol Aug 12 '17 at 15:37
  • 1
    @OsmanSenol: That post is not only unreadable on Chrome, but it certainly *appears* to have mistakes in it: 1) "So well, in short here for-each will create an enumerator object on each iteration" - no, the enumerator is created once; 2) The explanation of how `foreach` is implemented is incorrect - it *happens* that there's a `List.Enumerator` type, but that's not a general pattern; 3) `List.Enumerator` is a value type, at least in the main .NET framework, so I wouldn't expect *any* extra garbage collection. Maybe the version of Mono Unity3d is using is using a reference type for that? – Jon Skeet Aug 12 '17 at 15:40
  • @OsmanSenol: Point 1 is the most important there, particularly bearing in mind the later justification of "Well in this case you are right, but now imagine there is a case where you have to run through different loops with over 1000’s of iterations, each loop giving out few bytes of GC!" The "1000s of iterations" makes the impact of 40 bytes *per overall loop* even less relevant. – Jon Skeet Aug 12 '17 at 15:41
  • @OsmanSenol: I understand that in mobile gaming it's important to be conservative with allocations, but I suspect that at least in the *majority* of cases, the difference is irrelevant. – Jon Skeet Aug 12 '17 at 15:42

2 Answers2

8

Unless you need some specific logic if the list is empty, then the if statement is certainly redundant. In the foreach loop if there is no data - it simply does not perform the loop.

This is more or less of a concern for best practice rather than performance though. The impact is practically non-existent; however, I think its never a bad I idea to at least be aware of these type of things.

Chris Cruz
  • 1,829
  • 13
  • 15
  • 1
    Most of the times answerers start bashing on asking such things, such as measure before you need to oprimize, etc.. Your kind of answer will be very useful in such cases - telling about non-existent practical impact AND that its never a bad idea to be aware of the things. – Nitesh May 29 '20 at 05:50
1

The performance difference is almost certainly negligible (but it never hurts to measure).

On the other hand, a pure foreach will work for practically any collection, whereas using a for loop or checking Count (or Length or Count()) implicitly assumes that the collection is an IList.

So, you have three options that are (probably) equally performant, but one is vastly more flexible than the others.

Rodrick Chapman
  • 5,437
  • 2
  • 31
  • 32