0

Would there be any performance improvement to add a check of the count of a collection before enumerating the contents with foreach?

if (users.Count != 0) {
  foreach (var user in users) {
     // do what snowmen do in summer
  }
}

vs.

 foreach (var user in users) {
     // do what snowmen do in summer
  }

My function is taking a little too long, so I'd like to know if this will improve performance even a little to get my function execution time down to where I need it.

Edit (context in which this loop executes):

for (DateTime day = dayStart; day < dayEnd; day = day.addMinutes(30)) {
  // Other actions
  if (users.Count != 0) {
    foreach (var user in users) {
       // do what snowmen do in summer
    }
  }
}
James
  • 3,551
  • 1
  • 28
  • 38
Magic-Mouse
  • 603
  • 10
  • 21
  • 5
    That is called premature optimization. The only reason why you should use `if(users.Any())` or `if(users.Count != 0)` is that you want to handle the case that there are no users. – Tim Schmelter Oct 13 '14 at 11:14
  • 1
    Did you try it? Probably doesn't make any difference though. – harold Oct 13 '14 at 11:14
  • 4
    No; it's no an improvement: optimizer can do such easy trick by itself. If you're lloking for faster implementation, scrutinize the code *within* `foreach` loop. – Dmitry Bychenko Oct 13 '14 at 11:17
  • @TimSchmelter thanks for a fast reply – Magic-Mouse Oct 13 '14 at 11:21
  • Not an improvement, actually if statement here will only be handy in case you want to handle the if-else case like @TimSchmelter said, otherwise in case you want to check/prevent for null reference exception: if(users == null) return; – Nawed Nabi Zada Oct 13 '14 at 11:27
  • 1
    You have to measure, it greatly depends on the likelihood that the processor can predict the branch. Mispredicted branches are very expensive. Covered well in [this post](http://stackoverflow.com/a/11227902/17034). – Hans Passant Oct 13 '14 at 14:18
  • 1
    On modern processors, [for and for-each loops compile to roughly an if-statement wrapped around a do-while](http://stackoverflow.com/questions/20172402/do-compilers-produce-better-code-for-do-while-loops-versus-other-types-of-loops). That implicit if-statement precisely checks for zero. So wrapping another (redundant) if-statement could actually be a *pessimization* if the compiler doesn't remove it. – Mysticial Oct 13 '14 at 21:00
  • I don't know what level this is predicted, but since the activity is more likely between 08:00 and 18:00 and verry unlikely between 22:00 and 04:00 it is pretty predictable, atleast by a human mind. – Magic-Mouse Oct 14 '14 at 06:23

2 Answers2

9

The two scripts have the same results.

Foreach will not do anything if the count is zero, so no need for if statement.

It is not faster the difference of execution in nano seconds and bigger, it will be slower in case the list have items but you will not notice anything in the two cases.

oussama abdou
  • 317
  • 1
  • 7
  • im aware that the result is the same, what i wonder is if the "if" is faster than foreach(var x (where x.count = 0) in y)? – Magic-Mouse Oct 13 '14 at 11:18
  • 1
    Strictly speaking it's not the same since the `if` prevents that that `GetEnumerator` needs to be executed. But the sole reason why it could be important to use an `if` is that you want to handle the case that there are no users in the `else`. – Tim Schmelter Oct 13 '14 at 11:19
  • 1
    The two have the same Results but not same execution. no it is not faster the difference in nano seconds or more and it will be slower in case the list have items but you will not notice anything in the two cases. – oussama abdou Oct 13 '14 at 11:23
  • Yes @oussamaabdou that was the answer i was looking for, can you formulate it and then i will give you credit. – Magic-Mouse Oct 13 '14 at 11:37
0

The first version is probably a degradation.

Chances are great that the first instruction in the foreach is a quick test for emptiness. So you are essentially repeating twice the same.

In any case, such an "nano-optimization" has no visible effect in practice.

(Unless in a large majority of the cases, Count is zero.)

  • Even if `Count` is zero in all cases, I doubt an explicit `If`-`then`-`else` trap will be significantly more efficient than the immediately-terminating `ForEach` loop. – TheBlastOne Oct 13 '14 at 13:54
  • That's unsure, it depends on the type of the `users` object; there could be some initialization before the exit test. –  Oct 13 '14 at 16:05