Какой самый простой способ составления профиля PHP-скрипта?
Я бы хотел добавить что-то, что покажет мне дамп всех вызовов функций и за какое время они выполнялись.
Я пробовал экспериментировать с функцией microtime:
$then = microtime();
myFunc();
$now = microtime();
echo sprintf("Elapsed: %f", $now-$then);
но иногда это дает отрицательные результаты. К тому же это очень хлопотно — проставлять вызовы по всему коду.
Ответ 1
Расширение PECL APD используется следующим образом:
<?php
apd_set_pprof_trace();
//rest of the script
?>
После этого проанализируйте сгенерированный файл, используя pprofp.
Пример вывода:
Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time = 0.00
Total User Time = 0.00
Real User System secs/ cumm
%Time (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00 0.00 0.00 0.00 0.00 1 0.0000 0.0009 0 main
56.9 0.00 0.00 0.00 0.00 0.00 0.00 1 0.0005 0.0005 0 apd_set_pprof_trace
28.0 0.00 0.00 0.00 0.00 0.00 0.00 10 0.0000 0.0000 0 preg_replace
14.3 0.00 0.00 0.00 0.00 0.00 0.00 10 0.0000 0.0000 0 str_replace
Ответ 2
Думаю, вам нужен xdebug. Установите его на сервер, включите, прокачивайте вывод через kcachegrind (для Linux) или wincachegrind (для Windows), и он покажет вам несколько подробных диаграмм, в которых указаны точные тайминги, счетчики и использование памяти.
Ответ 3
Никаких расширений не требуется, просто используйте эти две функции для простого профилирования.
// Вызывайте эту функцию в каждой интересующей точке, передавая описательную строку
function prof_flag($str) {
global $prof_timing, $prof_names;
$prof_timing[] = microtime(true);
$prof_names[] = $str;
}
// Вызовите эту функцию, когда захотите увидеть результаты
function prof_print() {
global $prof_timing, $prof_names;
$size = count($prof_timing);
for($i=0;$i<$size - 1; $i++) {
echo "<b>{$prof_names[$i]}</b><br>";
echo sprintf(" %f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
}
echo "<b>{$prof_names[$size-1]}</b><br>";
}
Вот пример вызова prof_flag() с описанием для каждой контрольной точки и prof_print() в конце:
prof_flag("Запуск");
include '../lib/database.php';
include '../lib/helper_func.php';
prof_flag("Подключиться к БД");
connect_to_db();
prof_flag("Выполнить запрос");
// получение данных
$select_query = "SELECT * FROM data_table";
$result = mysql_query($select_query);
prof_flag("Получить данные");
$rows = array();
$found_data=false;
while($r = mysql_fetch_assoc($result)) {
$found_data=true;
$rows[] = $r;
}
prof_flag("Закрыть БД");
mysql_close();
prof_flag("Завершение");
prof_print();
Результат выглядит так:
Запуск
0.004303
Подключиться к БД
0.003518
Выполнить запрос
0.000308
Получить данные
0.000009
Закрыть БД
0.000049
Завершение
Ответ 4
Профилирование с помощью XDebug
Расширение для PHP под названием Xdebug доступно для помощи в профилировании приложений PHP, а также при отладке во время выполнения. При запуске профилировщика выходные данные записываются в файл в двоичном формате под названием «cachegrind». На каждой платформе доступны приложения для анализа этих файлов. Для выполнения этого профилирования не требуется никаких изменений кода приложения.
Чтобы включить профилирование, установите расширение и настройте параметры php.ini. Некоторые дистрибутивы Linux поставляются со стандартными пакетами (например, php-xdebug пакет Ubuntu). В нашем примере мы запустим профиль необязательно на основе параметра запроса. Это позволяет нам сохранять настройки статичными и включать профилировщик только по мере необходимости.
# php.ini settings
# Установите значение 1, чтобы включить его для каждого запроса
xdebug.profiler_enable = 0
# Используем параметр GET/POST для включения профилировщика
xdebug.profiler_enable_trigger = 1
# Значение GET/POST, которое мы будем передавать; пусто для любого значения
xdebug.profiler_enable_trigger_value = ""
# Выведите файлы cachegrind в /tmp, чтобы наша система очистила их позже.
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"
Затем используйте веб-клиент, чтобы сделать запрос на URL-адрес вашего приложения, который вы хотите профилировать, например:
http://example.com/article/1?XDEBUG_PROFILE=1
По мере обработки страницы она будет записывать в файл с именем, похожим на:
/tmp/cachegrind.out.12345
По умолчанию число в имени файла — это идентификатор процесса, который его написал. Это можно настроить с помощью параметра xdebug.profiler_output_name.
Обратите внимание, что он будет записывать один файл для каждого выполняемого запроса/процесса PHP. Так, например, если вы хотите проанализировать сообщение формы, один профиль будет написан для запроса GET для отображения HTML-формы. Параметр XDEBUG_PROFILE необходимо будет передать в последующий запрос POST для анализа второго запроса, обрабатывающего форму. Поэтому при профилировании иногда проще запустить curl для POST формы напрямую.
Cachegrind, например, отобразит такую информацию так:
Выполненные функции
Время вызова как самой функции, так и включая последующие вызовы функций
Количество вызовов каждой функции
Графики вызовов
Ссылки на исходный код
Web