Код бенчмаркинга отличается внутри и снаружи цикла foreach

У меня есть раздел кода, который выглядит примерно так:

$this->benchmark->mark('start1');
$timer = 0;
foreach($x as $y)
{
$this->benchmark->mark('start2');
// Some code here
$this->benchmark->mark('end2');
$timer = $timer + $this->benchmark->elapsed_time('start2','end2');
}
var_dump('Timer = '.$timer);
$this->benchmark->mark('end1);
var_dump('Total = '.$this->benchmark->elapsed_time('start1','end1') );

Это дает мне что-то вроде

Timer = 0.43466
Total = 45.34421

Как это возможно? Они должны быть в значительной степени идентичны.

0

Решение

Я думаю, что проблема немного похожа на дуальность волны и частицы фотона в квантовой механике. Или это ошибка в функции PHP microtime();

Пытаясь понять это, я сначала заподозрил, что benchmark->elapsed_time была проблема, потому что он возвращает строку. Но это не было связано вообще.

Чтобы быть уверенным, что это не было частью проблемы, которую я взял benchmark вне уравнения и используется microtime() непосредственно. benchmarkкласс в основном только использует microtime() во всяком случае, но я хочу быть уверен.

Вот моя первая итерация

class Profiling extends CI_Controller
{
public function index()
{
$param = 3000000;
$start_1 = microtime(TRUE);
$timer = $this->long_exec_time($param);
$end_1 = microtime(TRUE);
echo "Timer";
var_dump($timer);
$total = $end_1 - $start_1;
echo "Total";
var_dump($total);
}

public function long_exec_time($param)
{
$timer = 0;
for($i = 1; $i < $param; $i++)
{
$start_2 = microtime(TRUE);
sqrt($i);
$timer += (microtime(TRUE) - $start_2);
}
return $timer;
}

}

Какие выводы

таймер

float 3.8147616386414

Всего

float 6.5267660617828

Похоже, ваша проблема. И на самом деле это занимает более 6 секунд, чтобы выполнить.

Но если функция long_exec_time определяется так

public function long_exec_time($param)
{
$timer = 0;
$start_2 = microtime(TRUE);
for($i = 1; $i < $param; $i++)
{
sqrt($i);
}
$timer += (microtime(TRUE) - $start_2);
return $timer;
}

Выход

таймер

float 2.3692939281464

Всего

float 2.3693020343781

И да, это фактическое время выполнения.

Это, безусловно, указывает на повторные призывы к microtime(TRUE) вызывая более длительное общее время выполнения.

Но почему эти две суммы не совпадают, для меня загадка. По логике они должны быть намного ближе по стоимости. Единственное, что приходит на ум, это то, что microtime имеет свои проблемы. Я обнаружил сообщения об утечках памяти в функции в определенных средах. Но я не уверен, как это будет способствовать странной разнице — если это будет способствовать.

Все, что сказал, я почти уверен, если вы удалите звонки $this->benchmark->mark внутри вашего foreach петли все пойдет намного быстрее.

0

Другие решения

Других решений пока нет …