Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The code represented by the ellipsis will almost certainly relegate any <em>actual</em> performance difference to mere noise. However, you're not correct in all of your assumptions.</p> <blockquote> <p>every iteration will require loading max into a register in the processor and then compare between i and max</p> </blockquote> <p>Maybe, but probably not. This depends on your code, but any sane optimizing compiler will be able to detect if the counter is changing between iterations. </p> <p>I'm not sure where you got some of your ideas, but they are a bit misguided and don't take into account how an optimizing compiler works. Look at your disassembly and see what the real difference is yourself. Oh what the hell, I'll do it (it's fun anyway):</p> <p>The program is:</p> <pre><code>int main(int argc, char *argv[]){ int max = 10; for (int i = max-1; i &gt;= 0; i--) { cout &lt;&lt; i; } return 0; } </code></pre> <p>The generated assembly (VS2010 release, comments my own) is:</p> <pre><code>int main(int argc, char *argv[]){ 00341000 push esi int max = 10; for (int i = max-1; i &gt;= 0; i--) 00341001 mov esi,9 ; move a static 9 into esi 00341006 jmp main+10h (341010h) 00341008 lea esp,[esp] ; load the address of whatever 0034100F nop ; esp points to in memory { ; (not a memory fetch, just address calculation) cout &lt;&lt; i; 00341010 mov ecx,dword ptr [__imp_std::cout (342048h)] 00341016 push esi 00341017 call dword ptr [__imp_std::basic_ostream&lt;char,std::char_traits&lt;char&gt; &gt;::operator&lt;&lt; (342044h)] 0034101D dec esi ; decrement counter 0034101E jns main+10h (341010h) ; jump if not signed } </code></pre> <p>And for the more idiomatic version...</p> <pre><code>int main(int argc, char *argv[]){ 00AC1000 push esi int max = 10; for (int i = 0; i &lt; max; i++) 00AC1001 xor esi,esi { cout &lt;&lt; i; 00AC1003 mov ecx,dword ptr [__imp_std::cout (0AC2048h)] 00AC1009 push esi 00AC100A call dword ptr [__imp_std::basic_ostream&lt;char,std::char_traits&lt;char&gt; &gt;::operator&lt;&lt; (0AC2044h)] 00AC1010 inc esi ; increment esi 00AC1011 cmp esi,0Ah ; compare to 10 (0Ah) 00AC1014 jl main+3 (0AC1003h) ; if less, jump to top } </code></pre> <p>So yes, the first version uses a <code>jns</code> instruction (jump if not signed), so the comparison is simplified a bit (comparing to 0). It also contains a few more instructions, but no comparison. </p> <p>However, notice that the comparison made in version two is also static. It knows that <code>max</code> doesn't change throughout the loop, so it can optimize that bit accordingly.</p> <p><em>But</em> I would reiterate strongly that this is not likely to ever produce an appreciable performance benefit. Even the high performance timer on my Windows PC couldn't give me a good statistical difference between the two because the call to <code>cout</code> takes soooo much longer than the loop instructions.</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.
    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