#php #performance #do-while
#php #Производительность #do-while
Вопрос:
Я профилировал циклы for, 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 выполняется по крайней мере один раз).
Я знаю, что общее мнение таково, что циклы while не одобряются, а do-while — тем более.
Мой вопрос в том, почему? Учитывая, сколько циклов for используется в приложениях PHP, не следует ли использовать больше do -while? Даже при использовании инструкции if для проверки условия перед выполнением цикла повышение производительности является значительным.
Мой принятый в настоящее время ответ заключается в том, что разборчивость кода является подозрительной.
10-летняя правка: 10 лет назад мне задали этот вопрос на собеседовании при приеме на работу. Я пришел на собеседование с неверным представлением о том, что циклы while вызывали неодобрение. Я научился этому на своей предыдущей работе, где циклы while не были разрешены в коде, согласно инструкциям моего начальника.
Собеседование с руководством прошло хорошо, затем меня передали ведущему программисту, он спросил меня, какой самый быстрый цикл в PHP, на что я ответил неправильно, и я не получил работу, вот почему я задал вопрос на SO.
10-летний опыт многому меня научил.
- хотя циклы в порядке (нелепо думать, что меня учили иначе)
- Микрооптимизация — это настоящее зло (код профиля, фокус на горлышках бутылок)
- за 10 лет я ни разу не переписывал цикл для ускорения. Однако я переписал логику внутри цикла, которая всегда была истинным узким местом.
- В области программирования существует множество устоявшихся, но в основном неверных мнений. Придерживайтесь выбранного курса, читайте, экспериментируйте и задавайте вопросы, будьте открыты для обучения у лучших программистов и не бойтесь ошибаться.
Комментарии:
1. Можете ли вы опубликовать результаты своего бенчмаркинга?
2. Я никогда не видел такого консенсуса, что циклы while плохие. Они являются инструментом в PHP toolkit, как и любой другой.
3. Кто не одобряет циклы while? Использование только половины времени звучит как много, но вы должны измерить фактическое время, которое вы экономите. Вы экономите половину ничего.
Ответ №1:
- Микрооптимизация — это зло. Они снижают читаемость без заметного прироста производительности. Даже если в вашем приложении есть циклы с миллионами итераторов (в чем я сомневаюсь), разница все равно незначительна.
- Разница между
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
цикле есть только один оператор перехода (JMPNZ
), тогда как дляwhile
цикла требуется два (JMPZ
,JMP
).for
Циклу требуются три оператора перехода (JMPZNZ
,JMP
,JMP
) и, как правило, он имеет более сложную логику.
Комментарии:
1. Я так не думаю. Если ему за это заплатят. Если ему это нравится. Когда у него миллион итераторов, тогда это имеет смысл.
2. @Jitamaro даже если есть миллионы итераций, разница между while / do-while / for почти всегда незначительна по сравнению со временем, затраченным на выполнение чего-либо внутри цикла.
3. Цикл незначителен, скорость алгоритма, занимаемая память важнее
4. @Jitamaro: Нет, они злые. Если вы не уверены, прочтите этот пост в блоге на эту тему…
5. @icrmaxell: Я просмотрел статью, на которую вы ссылались, но она неправильная. Этих правил 90/10 не существует. Это называется правилом Парето и оно говорит о 80/20 процентах.
Ответ №2:
Если вас интересуют такого рода вещи, вам может показаться интересным PHPBench.
Мое личное мнение таково, что вам следует использовать циклы while, do и for там, где они наиболее разборчивы. Увеличение скорости на 6% в пустом цикле недостаточно значительно, если вы проводите большую часть своего времени в базе данных.
Ответ №3:
Если вам нужен быстрый цикл, вы должны развернуть его или использовать duff-устройство.
Вы также можете сократить цикл for (демо):
for ($var = 0; $var < 10; ) {
// do nothing
}
Вы также можете сократить цикл do-while (демо):
$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 ;
}
?>
(Это модифицированная форма оригинального устройства Duff, потому что 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