Измерение прошедшего времени между сегментами кода в PHP
Время от времени я хотел бы иметь возможность измерять прошедшее время между двумя сегментами кода. Это исключительно для того, чтобы обнаружить узкие места в коде и улучшить то, что можно улучшить.
Я хотел бы создать такую функцию, в которой функция должна работать с глобальной переменной, которая отбирает прошедшее время между текущим вызовом и в последний раз, когда он был вызван.
Таким образом, вы можете использовать его много раз один за другим.
И функция должна быть способна вычислять различия в доли секунды, такие как 0,1 с или 0,3 с и т.д.
Пример, вероятно, объяснит это намного лучше.
echo time_elapsed();
// This echo outputs nothing cause this is the starting case.
// There is nothing to compare against.
//
// 1st code section here
//
echo time_elapsed();
// This echo outputs 0.5 seconds.
// ...which means there has been 0.5 seconds passed
// ...since the last time time_elapsed() was fired
//
// 2nd code section here
//
echo time_elapsed()
// This echo outputs 0.2 seconds
//
// 3rd code section here
//
echo time_elapsed()
// This echo outputs 0.1 seconds etc
Мой вопрос в том, какие PHP-утилиты (встроенные функции) мне нужно использовать для достижения такого вида вывода?
Ответы
Ответ 1
Отладчик, такой как XDebug/Zend Debugger, может дать вам этот вид понимания (и многое другое), но вот подсказка о том, как вы можете написать такую функцию:
function time_elapsed()
{
static $last = null;
$now = microtime(true);
if ($last != null) {
echo '<!-- ' . ($now - $last) . ' -->';
}
$last = $now;
}
В основном функция microtime() - это все, что вам нужно для выполнения вычислений времени. Чтобы избежать глобальной переменной, я использую статическую переменную в рамках прошедшей функции. Кроме того, вы можете создать простой класс, который может инкапсулировать требуемые переменные и вызвать вызовы методу класса для отслеживания и вывода значений времени.
Ответ 2
Из первого примера в php doc s:
<?php
/**
* Simple function to replicate PHP 5 behaviour
*/
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
// Sleep for a while
usleep(100);
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "Did nothing in $time seconds\n";
Ответ 3
Что-то в этом направлении должно работать:
$start = microtime(true);
// Do something
sleep(2);
$end = (microtime(true) - $start);
echo "elapsed time: $end";
Ответ 4
Другие факторы влияют на время ваших сценариев. Пример:
- Сложный код и рекурсивные функции.
- Тип используемого веб-сервера, например: общий выделенный выделенный хостинг VS.
Ответ 5
Функция же drew010 (спасибо!), добавила пользовательские комментарии и отображения времени в микросекундах (нас):
function time_elapsed($comment)
{
static $time_elapsed_last = null;
static $time_elapsed_start = null;
// $unit="s"; $scale=1000000; // output in seconds
// $unit="ms"; $scale=1000; // output in milliseconds
$unit="μs"; $scale=1; // output in microseconds
$now = microtime(true);
if ($time_elapsed_last != null) {
echo "\n";
echo '<!-- ';
echo "$comment: Time elapsed: ";
echo round(($now - $time_elapsed_last)*1000000)/$scale;
echo " $unit, total time: ";
echo round(($now - $time_elapsed_start)*1000000)/$scale;
echo " $unit -->";
echo "\n";
} else {
$time_elapsed_start=$now;
}
$time_elapsed_last = $now;
}
Пример:
// Start timer
time_elapsed('');
// Do something
usleep(100);
time_elapsed('Now awake, sleep again');
// Do something
usleep(100);
time_elapsed('Game over');
Ouput:
<!-- Now awake, sleep again: Time elapsed: 100 us, total time: 100 us -->
<!-- Game over: Time elapsed: 100 us, total time: 200 us -->
Ответ 6
<?php
$time_start = microtime(true);
// Sleep for a while (or your code which you want to measure)
usleep(100);
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "Did nothing in $time seconds\n";
Источник: http://php.net/manual/en/function.microtime.php#example-2568
Ответ 7
Мои профилирующие потребности в разработке покрываются этим небольшим, но мощным классом:
<?php
class perflog {
protected $perflog = [];
public function start($tag) {
if (!isset($this->perflog[$tag])) $this->perflog[$tag] = 0;
$this->perflog[$tag] -= microtime(TRUE);
}
public function stop($tag) {
$this->perflog[$tag] += microtime(TRUE);
}
public function results() {
return $this->perflog;
}
}
Смотрите здесь в действии.
Он предназначен для вызова через последующие вызовы start(<tag>)
и stop(<tag>)
. Он создает массив с суммированным временем вашего кода, потраченным в разделах, заключенных вызовами start() и stop() с соответствующими тегами.
последовательности запуска-остановки могут быть вложенными и могут вводиться несколько раз, таким образом суммируя время, проведенное в закрытом разделе.
Его компактность обеспечивает минимальное воздействие на производительность. Создание динамического тэга можно использовать, чтобы программа могла изменять то, что он контролирует. Обычно это расширяется с помощью функций вывода или сохранения.