do-while-самый быстрый цикл в php?


Я профилировал для, while и do-while петли с чем-то простым:

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

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

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

Путем сравнения microtime() до и после циклов.

Цикл do-while в значительной степени является самым быстрым циклом. do-while На самом деле быстрее, чем while почти вдвое. Я знаю, что они предназначены для разных целей ( while проверяет условие перед выполнением цикла и do-while выполняет по крайней мере один раз ).

I знайте, что общее мнение таково, что в то время как петли хмурятся и делают-в то время как еще больше.

Мой вопрос-почему? Учитывая, сколько циклов for используется в приложениях PHP, не следует ли do-while использовать больше? Даже если операторif проверяет условие перед выполнением цикла, повышение производительности значительно.

Мой принятый в настоящее время ответ заключается в том, что разборчивость кода является подозрительной.

3 6

3 ответа:

  1. Микрооптимизация-это зло.. Они уменьшают читабельность для нет измеримый прирост производительности. Даже если в вашем приложении есть циклы с миллионами итераторов (в чем я сомневаюсь), разница все равно незначительна.
  2. разница между while / do while меньше, чем вы говорите: http://codepad.viper-7.com/M8cgt9
  3. Чтобы понять, почему do while немного быстрее, посмотрите на сгенерированный опкоды:

    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
    

    Цикл do while имеет только один оператор перехода (JMPNZ), в то время как цикл while нуждается в двух (JMPZ, JMP). Цикл for нуждается в трех операторах перехода(JMPZNZ, JMP, JMP) и имеет вообще более сложную логику.

Если вы заинтересованы в такого рода вещах, вы можете найти PHPBench интересным.

Мое личное мнение заключается в том, что вы должны использовать while, do и For loops, где они наиболее удобочитаемы. Увеличение скорости на 6% в пустом цикле недостаточно существенно, если вы проводите большую часть времени в базе данных.

Если вы хотите быстрый цикл, вы должны развернуть его или использовать устройство duff.

Вы также можете сократить цикл for (demo):

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

Вы также можете сократить цикл do-while (demo):

$var=0;
do {
    echo "Hello";
} while (++$var < 10);
Но опкоды те же самые.

А вот модифицированная версия устройства Даффа из 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++;
}
?>

(это модифицированная форма оригинального устройства Даффа, потому что PHP не понимает
вопиющий синтаксис оригинала.)

Это алгоритмически эквивалентно общей форме:

<?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