Профилирование PHP-кода
Рано или поздно каждый из нас сталкивается с унаследованным кодом и его оптимизацией. Дебаггер и профилировшик в такой ситуации - лучшие помощники программиста. У тех кто работает с PHP, благодаря Дерику Ретансу (Derick Rethans) есть хороший инструмент - xDebug. Информации касательно xDebug много даже в рунете, поэтому речь в этой статье пойдет не о нем.
Наткнувшись на упоминание о профилировщике для PHP я сразу подумал об xDebug ( о проприетарных инструментах от Zend я давно уже успел позабыть ), но на этот раз ошибся - речь пойдет об XHProf.
XHProf
Этот профилировшик был разработан специально для Facebook, а исходный код его был открыт в марте 2009 года.
Установка прошла достаточно быстро и гладко.
bash
wget http://pecl.php.net/get/xhprof-0.9.2.tgz tar xvf xhprof-0.9.2.tgz cd xhprof-0.9.2/extension/ phpize ./configure && make && make install cd /usr/local/etc/php.d/ vim xhprof.ini cd /usr/local/ vim header.php vim footer.php vim etc/php.ini /etc/init.d/php-fpm restart cp vhost.conf.template prof.my.conf sed -i s/site/prof/ prof.my.conf vim prof.my.conf /etc/init.d/nginx restart
Разберем упомянутые конфиги
xhprof.ini
ini
[xhprof] extension=/usr/local/lib/php/extensions/no-debug-non-zts-20090626/xhprof.so xhprof.output_dir="/home/max/www/profile/"
в php.ini я добавил 2 строки, разовор о которых пойдет ниже
ini
auto_prepend_file = /usr/local/header.php auto_append_file = /usr/local/footer.php
prof.my.conf - конфиг нгинкса - самый стандартный.
nginx
server { listen 80; server_name prof.my; charset utf8; root /usr/local/src/xhprof-0.9.2/xhprof_html ; location / { index index.php; } location ~ \.php$ { fastcgi_pass 127.0.0.1:12000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/src/xhprof-0.9.2/xhprof_html/$fastcgi_script_name; include fastcgi_params; } }
В /usr/local/src/xhprof-0.9.2/xhprof_html лежат PHP-исходники, создающие неплохой WEBGUI к профайлеру.
Итак о двух главных файлах:
header.php
php
<?php include_once '/usr/local/src/xhprof-0.9.2/xhprof_lib/utils/xhprof_lib.php'; include_once '/usr/local/src/xhprof-0.9.2/xhprof_lib/utils/xhprof_runs.php'; xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); }
footer.php
php
<?php $profiler_namespace = 'myapp'; // namespace for your application $xhprof_data = xhprof_disable(); $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace); // url to the XHProf UI libraries (change the host name and path) echo <<<OUT <a style="display:block; position: absolute; top: 0; text-align: center; width: 150px; font-weigth:bold; color:yellow; background: #495; font-size:18px; padding: 3px; height: 27px; -moz-border-radius: 0 0 13px 0 ;" href="$profiler_url" target="_blank">Profiler output</a> OUT; }
Теперь запускаем любой PHP-скрипт через веб и видим в левом верхнем углу ссылку на вывод профилировщика - именно для этого и был создан хост prof.my
Внимание! Что будет если в хедере и футере добавить проверку на куки? Правильно! Профилировщик будет срабатывать только для тех кто сможет его включить, а следовательно мы сможем исползовать профилировщик даже на продакшн и только для себя. На реальных данных, на реальных нагрузках. Круто?
Веб-интерфейс профилировщика выводит таблички си информацией о каждой функции и сообщает следующую информацию:
- Число вызовов каждой функции
- Wall-time, время затраченное на выполнение функций (включая ожидание ответов от сокетов, файловой системы и т.д.).
- CPU-time, время затраченное на выполнение функций (исключая ожидание ответов от сокетов, файловой системы и т.д.).
- Использование памяти
- Пиковое использование памяти
Есть возможность сортировки таблицы по любому из параметров
Информация по каждой функции делится еще на два вида Inclusive и Exclusive. Inclusive включает цифры использованные дочерними вызовами, а Exclusive не включает их. Так же есть возможность, кликнув на название функции увидеть информацию только по ней и функциям из которых она вызывалась и которые вызывались ей.
Если в системе установлен GraphViz, профилировщик нарисует вам граф вызовов
Скриншоты:







