do-while is the fastest loop in php?

Gambo picture Gambo · Nov 10, 2011 · Viewed 8.2k times · Source

I have profiled for, while and do-while loops with something simple:

while ($var < 1000000) {
  ++$var;
}

do {
  ++$var;
} while ($var < 1000000);

for ($var = 0; $var < 1000000; ++$var) {
  //do nothing
}

by comparing microtime() before and after the loops.

The do-while loop is by a considerable amount the fastest loop. do-while is actually faster than while by almost half. I know that they are for different purposes ( while checks the condition before the loop executes and do-while executes at least once ).

I know the general consensus is that while loops are frowned upon and do-while even more so.

My question is why? Considering how many for loops are used in PHP applications, shouldn't do-while be used more? Even with an if statement to check a condition before the loop executes, the performance boost is considerable.

My currently accepted answer is that code legibility is the suspect.

Answer

NikiC picture NikiC · Nov 10, 2011
  1. Micro optimizations are evil. They reduce readability for no measurable performance gain. Even if your application does have loops with millions of iterators (which I doubt) the difference is still negligible.
  2. The difference between while / do while is smaller than you say: http://codepad.viper-7.com/M8cgt9
  3. To understand why do while is marginally faster, look at the generated opcodes:

    line     # *  op                           fetch          ext  return  operands
    ---------------------------------------------------------------------------------
    # while loop
       3     0  >   ASSIGN                                                   !0, 0
       4     1  >   IS_SMALLER                                       ~1      !0, 1000000
             2    > JMPZ                                                     ~1, ->5
             3  >   PRE_INC                                                  !0
             4    > JMP                                                      ->1
             5  > > RETURN                                                   1
    # do while loop
       3     0  >   ASSIGN                                                   !0, 0
       4     1  >   PRE_INC                                                  !0
             2      IS_SMALLER                                       ~2      !0, 1000000
             3    > JMPNZ                                                    ~2, ->1
       4        > > RETURN                                                   1
    # for loop
       3     0  >   ASSIGN                                                   !0, 0
             1  >   IS_SMALLER                                       ~1      !0, 1000000
             2    > JMPZNZ                                        5          ~1, ->6
             3  >   PRE_INC                                                  !0
             4    > JMP                                                      ->1
             5  > > JMP                                                      ->3
             6  > > RETURN                                                   1
    

    The do while loop only has one jump statement (JMPNZ), whereas the while loop needs two (JMPZ, JMP). The for loop needs three jump statements (JMPZNZ, JMP, JMP) and has generally more complex logic.