У меня есть раздел кода, который выглядит примерно так:
$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
Как это возможно? Они должны быть в значительной степени идентичны.
Я думаю, что проблема немного похожа на дуальность волны и частицы фотона в квантовой механике. Или это ошибка в функции 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
петли все пойдет намного быстрее.
Других решений пока нет …