Я профилировал для 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 на самом деле быстрее, чем в то же время почти наполовину. Я знаю, что они предназначены для разных целей (в то время как проверяет условие до того, как цикл выполнит и сделает, пока выполняется хотя бы один раз).
Я знаю, что общий консенсус в том, что в то время как петли неодобрились и делают, а тем более.
Почему мой вопрос? Учитывая, сколько для циклов используется в PHP-приложениях, не следует делать – а можно использовать больше? Даже если оператор if проверяет условие до того, как цикл будет выполняться, повышение производительности будет значительным.
Мой принятый в настоящее время ответ заключается в том, что четкость кода является подозреваемым.
while
/ do while
меньше, чем вы говорите: http://codepad.viper-7.com/M8cgt9 Чтобы понять, почему в 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
while имеет только один оператор перехода ( JMPNZ
), тогда while
цикл while нуждается в двух ( JMPZ
, JMP
). Для цикла for
требуется три команды перехода ( JMPZNZ
, JMP
, JMP
) и, как правило, более сложная логика.
Если вам нужен быстрый цикл, вы должны развернуть его или использовать устройство duff.
Вы также можете сократить цикл for (loop):
for ($var = 0; ++$var < 10; ) { // do nothing }
Вы также можете использовать цикл do-while ( 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 eg, 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
Если вас это интересует, вы можете найти PHPBench интересным.
Мое личное мнение заключается в том, что вы должны использовать while, do и for loop, где они наиболее читаемы. Увеличение скорости на 6% в пустом цикле недостаточно значимо, если вы тратите большую часть своего времени в базе данных.