Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>While this is entirely a micro optimization that would never be the performance bottleneck. It interesting that the two are actually different, interestingly when you extract methods both the loops with VS2010 I get the following:</p> <pre><code>private static String forLoop(ref Int64 i) { String x; for (; FIVE_BN &gt; i; i++) x = null; //Replace with only ; in both loops and the for loop is faster return x; } private static void whileloop(ref String x, ref Int64 i) { while (FIVE_BN &gt; i++) x = null; //Replace with only ; in both loops and the for loop is faster } </code></pre> <p>And that is quite interesting... it shows that the two functions are indeed different.</p> <p>now when we replace the logic in the loop with <code>;</code> we get the following extracted methods instead:</p> <pre><code>private static Int64 forLoopShort(Int64 i) { for (; FIVE_BN &gt; i; i++) ; //Replace with only ; in both loops and the for loop is faster return i; } private static Int64 whileLoopShort(Int64 i) { while (FIVE_BN &gt; i++) ; //Replace with only ; in both loops and the for loop is faster return i; } </code></pre> <p>Which indicates why the loops run basically the same with this configuration.</p> <p>To work out how they're different when inline (and not extracted into methods) we need to see what the optimized CLR coded looks like (though the optimizer might actually remove any significant differences between the two functions).. That's something for a later edit.</p> <p>Edit:</p> <p>The CIL reveals the differences:</p> <p>The For loop has <code>.maxstack 2</code> but the while loop has <code>.maxstack 4</code>, otherwise there's a little diference in the order of operations due to the fact that the increment for the <code>while</code> happens at the start of the loop but the <code>for</code> operation happens at the end of the loop (change the content of the loop to <code>Console.WriteLine(i)</code> and see that the While loop will print from 1 but the For loop will print from 0 (both do the same number of loop iterations though).</p> <p>When the loop contents is just a <code>;</code> both loops are 2 lines shorter in CIL with the following lines removed (for both loops):</p> <pre><code>IL_0006: ldnull IL_0007: stloc.0 </code></pre> <p>However when we build in release the code is very different:</p> <p>The difference between <code>x = null;</code> and <code>;</code> is nothing, for either of the loops, as the optimizer has noticed that the value never changes to being not-null.</p> <p>The difference between the optimised for and while loops are as follows:</p> <p>CIL <code>for</code> loop:</p> <pre><code>IL_0000: ldc.i4.0 IL_0001: conv.i8 IL_0002: stloc.0 IL_0003: br.s IL_000a IL_0005: ldloc.0 IL_0006: ldc.i4.1 IL_0007: conv.i8 IL_0008: add IL_0009: stloc.0 IL_000a: ldc.i8 0x12a05f200 IL_0013: ldloc.0 IL_0014: bgt.s IL_0005 IL_0016: ret </code></pre> <p>And CIL <code>while</code> loop:</p> <pre><code>IL_0000: ldc.i4.0 IL_0001: conv.i8 IL_0002: stloc.0 IL_0003: ldc.i8 0x12a05f200 IL_000c: ldloc.0 IL_000d: dup IL_000e: ldc.i4.1 IL_000f: conv.i8 IL_0010: add IL_0011: stloc.0 IL_0012: bgt.s IL_0003 IL_0014: ret </code></pre> <p>So we can see that an optimised while loop is faster than a for loop by 2 operations, however it uses more stack space.</p> <p>The difference between these two seems entirely related to the difference in where the <code>i++</code> occurs.</p> <p>Indeed this is confirmed by making a new method:</p> <pre><code>private static void forLoopVeryShort() { string x; Int64 i = 0; for (; FIVE_BN &gt; i++;) ; //Replace with only ; in both loops and the for loop is faster } </code></pre> <p>The CIL code for this <code>for</code> method when built (in either release or debug) is identical to that of the <code>while</code> loop.</p> <p>There in lies your difference. For loops perform exactly the same as while loops when they're doing the exact same behaviour. The difference you noted is entirely due to running the code in debug and not release, combined with the JIT not always being as efficient as the release code optimizer.</p> <p>I have enjoyed this question, I learnt something out of it; I hope others do as well. +1</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload