Как я могу сказать, какой класс из многих (которые все выполняют одну и ту же работу) выполняется быстрее? Есть ли программное обеспечение для измерения этого?
У тебя есть (по крайней мере) два решения:
Довольно «наивный» использует microtime (true) до и после части кода, чтобы узнать, сколько времени прошло во время его выполнения; другие ответы говорили об этом и уже приводили примеры, так что я не буду больше говорить.
Это хорошее решение, если вы хотите сравнить несколько инструкций; например, сравнивать два типа функций — лучше, если это делается тысячи раз, чтобы убедиться, что любой «возмущающий элемент» усреднен.
Примерно так, так что если вы хотите знать, сколько времени потребуется для сериализации массива:
$before = microtime(true);
for ($i=0 ; $i<100000 ; $i++) {
serialize($list);
}
$after = microtime(true);
echo ($after-$before)/$i . " sec/serialize\n";
Не идеально, но полезно, и настройка не займет много времени.
Другое решение, которое работает довольно хорошо, если вы хотите определить, какая функция занимает много времени во всем сценарии, — это использовать:
Чтобы получить файлы профилирования, вы должны установить и настроить Xdebug; взгляните на Профилирование PHP-скриптов страница документации.
Обычно я не включаю профилировщик по умолчанию. (он генерирует довольно большие файлы и замедляет работу), но используйте возможность отправить параметр с именем XDEBUG_PROFILE
Как получить данные, чтобы активировать профилирование только для нужной мне страницы.
Связанная с профилированием часть моего php.ini выглядит так:
xdebug.profiler_enable = 0 ; Profiling not activated by default
xdebug.profiler_enable_trigger = 1 ; Profiling activated when requested by the GET parameter
xdebug.profiler_output_dir = /tmp/ouput_directory
xdebug.profiler_output_name = files_names
(Прочитайте документацию для получения дополнительной информации)
Этот скриншот из программы на C ++ в KcacheGrind: http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif
Вы получите то же самое с PHP-скриптами 😉
(Я имею в виду KCacheGrind; WinCacheGrind не так хорош, как KCacheGrind …)
Это позволяет вам получить хорошее представление о том, что занимает время в вашем приложении, и иногда оно определенно помогает найти функция, которая замедляет все ^^
Обратите внимание, что Xdebug считает время процессора, затраченное PHP; когда PHP ожидает ответа из базы данных (например), он не работает; только жду Так что Xdebug будет думать, что запрос БД не займет много времени!
Это должно быть профилировано на сервере SQL, а не PHP, так что …
Надеюсь, что это полезно 🙂
Повеселись !
Для быстрых вещей я делаю это (на PHP):
$startTime = microtime(true);
doTask(); // whatever you want to time
echo "Time: " . number_format(( microtime(true) - $startTime), 4) . " Seconds\n";
Вы также можете использовать профилировщик, как http://xdebug.org/.
Вот прямой ответ на ваш вопрос
Есть ли программное обеспечение для измерения этого?
Да, есть. Мне интересно, почему никто еще не упомянул об этом. Хотя предложенные выше ответы кажутся хорошими для быстрой проверки, но они не масштабируются в долгосрочной перспективе или для более крупного проекта.
Почему бы не использовать инструмент мониторинга производительности приложений (APM), созданный именно для этого, и многое другое. Проверьте NewRelic, AppDynamics, Ruxit (у всех есть бесплатная версия), чтобы отслеживать время выполнения, использование ресурсов, пропускную способность каждого приложения на уровне метода.
Я сделал простой класс синхронизации, может быть, он кому-то пригодится:
class TimingHelper {
private $start;
public function __construct() {
$this->start = microtime(true);
}
public function start() {
$this->start = microtime(true);
}
public function segs() {
return microtime(true) - $this->start;
}
public function time() {
$segs = $this->segs();
$days = floor($segs / 86400);
$segs -= $days * 86400;
$hours = floor($segs / 3600);
$segs -= $hours * 3600;
$mins = floor($segs / 60);
$segs -= $mins * 60;
$microsegs = ($segs - floor($segs)) * 1000;
$segs = floor($segs);
return
(empty($days) ? "" : $days . "d ") .
(empty($hours) ? "" : $hours . "h ") .
(empty($mins) ? "" : $mins . "m ") .
$segs . "s " .
$microsegs . "ms";
}
}
Использование:
$th = new TimingHelper();
<..code being mesured..>
echo $th->time();
$th->start(); // if it's the case
<..code being mesured..>
echo $th->time();
// result: 4d 17h 34m 57s 0.00095367431640625ms
Я использую XHProf в последнее время http://pecl.php.net/package/xhprof. Первоначально он был разработан Facebook и имеет приличный веб-интерфейс.
Я хотел бы поделиться с вами самодельной функцией, которую я использую для измерения скорости любой существующей функции, до 10 аргументов:
function fdump($f_name='', $f_args=array()){
$f_dump=array();
$f_result='';
$f_success=false;
$f_start=microtime();
$f_start=explode(' ', $f_start);
$f_start=$f_start[1] + $f_start[0];
if(function_exists($f_name)){
if(isset($f_args[0])&&is_array($f_args[0])){
if($f_result=$f_name($f_args)){
$f_success=true;
}
}
elseif(!isset($f_args[1])){
if($f_result=$f_name($f_args[0])){
$f_success=true;
}
}
elseif(!isset($f_args[2])){
if($f_result=$f_name($f_args[0],$f_args[1])){
$f_success=true;
}
}
elseif(!isset($f_args[3])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){
$f_success=true;
}
}
elseif(!isset($f_args[4])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){
$f_success=true;
}
}
elseif(!isset($f_args[5])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){
$f_success=true;
}
}
elseif(!isset($f_args[6])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){
$f_success=true;
}
}
elseif(!isset($f_args[7])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){
$f_success=true;
}
}
elseif(!isset($f_args[8])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){
$f_success=true;
}
}
elseif(!isset($f_args[9])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){
$f_success=true;
}
}
elseif(!isset($f_args[10])){
if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){
$f_success=true;
}
}
}
$f_end=microtime();
$f_end=explode(' ', $f_end);
$f_end=$f_end[1] + $f_end[0];
$f_time=round(($f_end - $f_start), 4);
$f_dump['f_success']=$f_success;
$f_dump['f_time']=$f_time;
$f_dump['f_result']=$f_result;
var_dump($f_dump);exit;
//return $f_result;
}
пример
function do_stuff($arg1='', $arg2=''){
return $arg1.' '.$arg2;
}
fdump('do_stuff',array('hello', 'world'));
Возвращает
array(3) {
["f_success"]=>
bool(true)
["f_time"]=>
float(0) //too fast...
["f_result"]=>
string(11) "hello world"}
Если вы хотите быстро протестировать производительность фреймворка, вы можете вставить index.php файл
//at beginning
$milliseconds = round(microtime(true) * 1000);
//and at the end
echo round(microtime(true) * 1000) - $milliseconds;
Каждый раз, когда вы получите время выполнения в миллисекунды. Потому что микросекунды не слишком полезны при тестировании фреймворка.
Если это что-то, что можно протестировать вне веб-контекста, я просто использую Unix time
команда.