Пожалуйста, рассмотрите следующий код:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
continue 2;
}
}
echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
Учитывая, что приведенный выше код эффективно использует continue 2 для разрыва внутреннего цикла и пропуска любого кода после внутреннего цикла, почему следующий код в среднем выполняется быстрее, когда кажется, что он делает больше:
$start = microtime();
for($i = 2; $i < 100; $i++)
{
$flag = true;
for($y = 2; $y <= sqrt($i); $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
if($flag === true) echo $i.',';
}
echo "\nFinished in " . (microtime() - $start);
Спасибо за любой вклад.
_____ Обновление ______< /em>______
Спасибо за отзыв, но мы, кажется, упустили суть. Независимо от того, является ли это хорошей практикой программирования, я пытался понять, почему разница в производительности (которая крошечная, но постоянная) не находится в пределах ожидаемой мной предвзятости.
Переход от истинного к микровремени кажется незначительным, поскольку обе выборки измеряются с использованием одного и того же метода с одинаковыми накладными расходами и одинаковой неточностью.
Было протестировано более одного прогона, как следует из использования слова «среднее».
Просто для иллюстрации рассмотрите следующие небольшие примеры использования microtime(true), которые показывают тот же шаблон, что и использование microtime().
Я знаю, что это небольшая выборка, но схема вполне ясна:
Продолжить 0,00037288665771484 0,00048208236694336 0,00046110153198242 0,00039386749267578 0,0003662109375
Перерыв 0,00033903121948242 0,00035715103149414 0,00033307075500488 0,00034403800964355 0,00032901763916016
Спасибо за внимание и спасибо за любые дальнейшие отзывы.
______ ОБНОВЛЕНИЕ Дальнейшее расследование _____ _______
Интересно, что если операторы echo удалены из кода, то continue выполняется быстрее, а с операторами echo на месте break быстрее.
Пожалуйста, рассмотрите следующий пример кода и учтите, что результаты конфликтуют в зависимости от того, удалены операторы эха или нет:
<?php
$breakStats = array();
$continueStats = array();
ob_start();
for($i = 0; $i < 10000; $i++)
{
$breakStats[] = doBreakTest();
$continueStats[] = doContinueTest();
}
ob_clean();
echo "<br/>Continue Mean " . (array_sum($continueStats) / count($continueStats));
echo "<br/>Break Mean " . (array_sum($breakStats) / count($breakStats));
function doBreakTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$flag = true;
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
$flag = false;
break;
}
}
}
if($flag === true) echo $i . '';
return microtime(true) - $start;
}
function doContinueTest()
{
$start = microtime(true);
for($i = 2; $i < 100; $i++)
{
$root = sqrt($i);
for($y = 2; $y <= $root; $y++)
{
if($i%$y != 0)
{
continue;
}
else
{
echo $i . '';
continue 2;
}
}
}
return microtime(true) - $start;
}
Присутствуют эхо-утверждения:
Среднее значение продолжения 0,00014134283065796 Среднее значение перерыва 0,00012669243812561
Эхо-выражения отсутствуют:
Среднее значение продолжения 0,00011746988296509 Среднее значение перерыва 0,00013022310733795
Обратите внимание, что, удаляя оператор echo из теста break and flag, мы также удаляем проверку ($flag === true), поэтому нагрузка должна уменьшиться, но в этом случае continue все равно выигрывает. Вт
Таким образом, в чистом сценарии continue n против break + flag оказывается, что continue n является более быстрой конструкцией. Но добавьте равное количество идентичных операторов эха и флаги производительности continue n.
Для меня логически это имеет смысл, что continue n должен быть быстрее, но я ожидал увидеть то же самое с присутствующими операторами эха.
Это явно разница в сгенерированных кодах операций и позиции оператора эха (внутренний цикл по сравнению с внешним циклом). Кто-нибудь знает способ увидеть сгенерированные коды операций? Я полагаю, это в конечном счете то, что мне нужно, поскольку я пытаюсь понять, что происходит внутри.
Спасибо :)
microtime(TRUE)
, чтобы получить число с плавающей запятой, полезное для сравнения. - person mario   schedule 03.04.2011continue
иbreak
в циклах. Вместо этого рассмотрите возможность использованияwhile
. Не используйте функции в тестовом выражении циклаfor
. - person KingCrunch   schedule 03.04.2011continue <n>
. - person Josh Davis   schedule 03.04.2011