do-while самый быстрый цикл в php? - PullRequest
6 голосов
/ 10 ноября 2011

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

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

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

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

, сравнивая microtime () до и после циклов.

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

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

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

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

Ответы [ 3 ]

15 голосов
/ 10 ноября 2011
  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) и, как правило, имеет более сложную логику.

1 голос
/ 10 ноября 2011

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

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

1 голос
/ 10 ноября 2011

Если вы хотите быструю петлю, вы должны развернуть ее или использовать устройство для прослушивания.

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

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

Вы также можете сократить цикл выполнения ( demo ):

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

Но коды операций те же.

А вот модифицированная версия устройства duff от 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
...