Почему обратный цикл быстрее обычного (включая тест) - PullRequest
4 голосов
/ 10 апреля 2010

Я провел несколько небольших тестов в PHP на циклах. Я не знаю, если мой метод хорош.

Я обнаружил, что обратный цикл быстрее обычного цикла.

Я также обнаружил, что цикл while быстрее цикла for.

Настройка

<?php

$counter = 10000000;
$w=0;$x=0;$y=0;$z=0;
$wstart=0;$xstart=0;$ystart=0;$zstart=0;
$wend=0;$xend=0;$yend=0;$zend=0;

$wstart = microtime(true);
for($w=0; $w<$counter; $w++){
    echo '';
}
$wend = microtime(true);
echo "normal for: " . ($wend - $wstart) . "<br />";

$xstart = microtime(true);
for($x=$counter; $x>0; $x--){
    echo '';
}
$xend = microtime(true);
echo "inverse for: " . ($xend - $xstart) . "<br />";

echo "<hr> normal - inverse: " 
        . (($wend - $wstart) - ($xend - $xstart)) 
        . "<hr>";

$ystart = microtime(true);
$y=0;
while($y<$counter){
    echo '';
    $y++;
}
$yend = microtime(true);
echo "normal while: " . ($yend - $ystart) . "<br />";

$zstart = microtime(true);
$z=$counter;
while($z>0){
    echo '';
    $z--;
}
$zend = microtime(true);
echo "inverse while: " . ($zend - $zstart) . "<br />";

echo "<hr> normal - inverse: " 
        . (($yend - $ystart) - ($zend - $zstart)) 
        . "<hr>";

echo "<hr> inverse for - inverse while: " 
        . (($xend - $xstart) - ($zend - $zstart))
        . "<hr>";
?>

Средние результаты

Разница в контуре for

нормально для: 1.0908501148224
обратное значение для: 1.0212800502777

нормальный - обратный: 0,069570064544678

Разница в цикле while

нормально, а: 1.0395669937134
обратное время: 0,99321985244751
нормальное - обратное: 0,046347141265869

Разница в циклах for и while

обратный для - обратный, в то время как: 0.0280601978302

Вопросы

Мой вопрос: может ли кто-нибудь объяснить эти различия в результатах? И был ли мой метод сравнительного анализа верен?

1 Ответ

4 голосов
/ 10 апреля 2010

С обратным циклом for вы выполняете только один поиск переменной за итерацию:

$w > 0         // <-- one lookup to the $w variable

$w < $counter  // <-- two lookups, one for $w, one for $counter

Вот почему обратное немного быстрее. Кроме того, цикл while имеет только одну операцию на итерацию:

$w < $counter        // <-- one operation while loop

$w < $counter ; $w++ // <-- two operation for loop

Конечно, у вас есть эта дополнительная операция внутри блока кода цикла, но я точно не знаю, почему это быстрее (может, кто-то может заполнить пробел там) Вы заметите, что разница во времени минимальна, потому что эти операции все еще очень быстры. Такие микрооптимизации наиболее эффективны на очень больших петлях.

...