7

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.

10 year Edit: 10 years ago, I was asked this question at a job interview. I went into the interview with the incorrect perception that while loops were frowned upon. I learned this from my previous job where while loops were not allowed in code, as per instruction from my superior.

The interview had gone well with management, then I was handed over to the lead programmer, he asked me what the fastest loop in PHP was, which I got incorrect and I did not get the job, this is why I asked the question on SO.

10 years of experience has taught me a lot.

  1. while loops are fine (its ludicrous to think I was taught otherwise)
  2. Micro-optimizations are truly evil (profile code, focus on bottle necks)
  3. in 10 years, I have never re-written a loop for speed. I have however rewritten the logic inside the loop which was always the true bottleneck.
  4. There is a lot of strongly held but largely incorrect opinions in the programming field. Stay the course, read up, experiment and question, be open to learning from better programmers and dont be afraid to be wrong.
Gambo
  • 238
  • 1
  • 2
  • 9
  • Can you post your benchmarking results? – bot403 Nov 10 '11 at 15:07
  • 2
    I've never see this consensus that while loops are bad. They're a tool in the PHP toolkit, like any other. – Marc B Nov 10 '11 at 15:14
  • Who frowns upon while loops? Using only half the time sounds like a lot, but you should measure the actual time you are saving. You are saving the half of nothing. – martinstoeckli Nov 11 '11 at 08:17

3 Answers3

18
  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.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • I don't think so. If he is paid for it. If he likes it. When it has a million of iterators then it makes a sense. – Micromega Nov 10 '11 at 14:55
  • @Jitamaro even if there are millions of iterations the difference between while / do-while / for is almost always negligible compared to the time spent doing stuff inside the loop. – Marcus Nov 10 '11 at 15:03
  • The loop is negligible, the algorithm speed, memory taken is more important – andho Nov 10 '11 at 15:19
  • @Jitamaro: No, they are evil. If you're not convinced, read this [blog post](http://blog.ircmaxell.com/2011/08/on-optimization-in-php.html) on the subject... – ircmaxell Nov 10 '11 at 15:27
  • 1
    @icrmaxell: I've skimmed the article you linked but it's wrong. This 90/10 rules doesn't exist. It's called Pareto-Rule and it's saying 80/20 percent. – Micromega Nov 10 '11 at 15:35
  • @Jitamaro: That's a direct quote from Richard Pattis. So no, it's not wrong. You can argue with him as to 90/10 vs 80/20, but considering it's a cited source in the post, that doesn't make it wrong... – ircmaxell Nov 10 '11 at 15:44
  • But http://en.wikipedia.org/wiki/Vilfredo_Pareto is way older and has a wikipedia article. – Micromega Nov 10 '11 at 15:48
  • But it's useful to know the exact timings and to get the shortest timing for some applications? – Micromega Nov 10 '11 at 18:07
  • @Jitamaro It is useful to know why some things are slower than others (simply because it widens your horizon about internals), but usually applying those optimizations isn't worth it. – NikiC Nov 10 '11 at 18:29
1

If you want a fast loop you must unroll it or use a duff device.

You can also shortcut the for-loop (demo):

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

You can also shortcut the do-while loop (demo):

$var=0;
do {
    echo "Hello";
} while (++$var < 10);

But the opcodes are the same.

And here is a modified version of the duff device from php.net:

If you're already using the fastest algorithms you can find (on the order of O(1),      
O(n), or O(n log n)), and you're still worried about loop speed, unroll your loops  
using e.g., Duff's Device:

<?php
$n = $ITERATIONS % 8;
while ($n--) $val++;
$n = (int)($ITERATIONS / 8);
while ($n--) {
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
  $val++;
}
?>

(This is a modified form of Duff's original device, because PHP doesn't understand the
original's egregious syntax.)

That's algorithmically equivalent to the common form:

<?php
 for ($i = 0; $i < $ITERATIONS; $i++) {
   $val++;
}
?>

$val++ can be whatever operation you need to perform ITERATIONS number of times.

On my box, with no users, average run time across 100 samples with ITERATIONS =     
10000000 (10 million) is:
Duff version:       7.9857 s
Obvious version: 27.608 s
Micromega
  • 12,486
  • 7
  • 35
  • 72
1

If you're interested in that kind of thing, you may find PHPBench interesting.

My personal opinion is that you should use while, do and for loops where they are most legible. A 6% speed increase on an empty loop isn't significant enough if you're spending most of your time in the database.

Gustav Bertram
  • 14,591
  • 3
  • 40
  • 65