17

Do I have to optimize my FOR-loops like below or the compiler will do that for me?

//this is slow, right?
for (int i = 0; i < menuItem.DropDownItems.Count; i++)
{
    ...
}

//this should be much faster right?
for (int i = 0, count = menuItem.DropDownItems.Count; i < count; i++)
{
    ...
}

PS. I bet this was already posted but I haven't found anything, sorry for a possible dup.

PPS. Sorry, I code a lot of JavaScript - where we have to think these kind of optimizations... May seem ridiculous in .net-world.

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
  • 10
    You've written the code both ways. If you want to know which is faster *run them both, measure the timing of each, and then you'll know*. No need to ask the internet to make a guess when you can get a definitive answer yourself in a few seconds. – Eric Lippert Dec 18 '10 at 15:17

2 Answers2

20

Well, it depends on how DropDownItems.Count is implemented - but frankly it's likely to be a simple field-backed property... which would make the first code just as fast as the second, but much more readable.

Readability first - then measure performance and micro-optimize only where necessary.

Where possible, prefer a foreach loop to start with though... again, on grounds of readability.

Even if you do want to use a temporary variable, I would keep the for loop itself simple, hoising the count out to separate variable. Admittedly it means a wider scope, but it's simpler:

int count = menuItem.DropDownItems.Count;
for (int i = 0; i < count; i++)
{
    ...
}

That much is just personal preference though.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • +1 for the "Readability first" comment. :) However, a `foreach` loop wouldn't work directly here because of the cast, right? So it would incur extra casts at each iteration. – user541686 Dec 18 '10 at 08:30
  • @Lambert: It's hard to tell at the moment, as we haven't seen any of the code in the loop. But if there's a cast due to the `foreach` there'd usually be a cast in the loop body with a `for` anyway. – Jon Skeet Dec 18 '10 at 08:37
  • 2
    Agree, also with this UI stuff shaving of that nanosecond is not going to light up anyones day really. This stuff is peanuts compared to the time it takes to repaint the screen. Concentrate on a responsive UI by not blocking the UI thread, that will put a smile on the users face. – gjvdkamp Dec 18 '10 at 08:40
  • @Jon: The issue with the cast is, `foreach` uses `IEnumerable`, so the cast is mandatory. However, the indexer directly accesses the list, which doesn't need a cast (assuming the list itself is strongly typed, which I haven't checked). So it could save some casts. @gjvdkamp: I agree with you on parts of it. There's certain things that are rather insignificant (like the cast here), but I've seen some situations first-hand, very similar to here, where multiple evaluations of `Count` slow down the GUI dramatically. (I'll post some code if I find it.) It's not always all that insignificant. – user541686 Dec 18 '10 at 09:06
  • @Lambert: `foreach` will use `IEnumerable` when it's available of course... at which point the cast can usually be removed. The only time a cast is necessary with `foreach` but not without it is if the indexed access is strongly typed (with no internal casts) but it only implements `IEnumerable`. Even so, I'd always write the most readable code first and measure it before micro-optimizing. – Jon Skeet Dec 18 '10 at 20:06
  • @Jon: (When I said `foreach` uses `IEnumerable` I meant this specific example, not in general.) And yeah, I generally agree about the code-then-measure rule. :) – user541686 Dec 19 '10 at 04:04
  • "it depends on how DropDownItems.Count is implemented" - ok, let's say it RECOUNTS every time, what would be the answer? PS. I asked "does the compiler optimizes that?" a simple "no" would do. :) – Alex from Jitbit Dec 19 '10 at 21:22
  • @jitbit: No, the compiler doesn't optimize it. In that case, the first form *would* be better... but I'd be very surprised to see a collection implemented like that :) – Jon Skeet Dec 19 '10 at 22:08
0

What's the ... part? In any question of this sort, my first response is to ask "Does it even matter, in this case?" Performance is always relative. If that exact line of code is on the stack or at the end of it more than 10% of the time, then it's worth worrying about, and that is usually very unlikely.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135