Профилирование кода позволяет выявить медленные участки в коде, что позволит в случае необходимости устранить их.
Новый PHP профайлер XHprof от компании Facebook — это альтернатива Xdebug (). XHprof был разработан специально для Facebook и начиная с март 2009 года его исходный код стал доступен для скачивания. Как работает XHprof?
XHProf работает по принципу декомпозиции системы на вызовы функций (методов) и построения статистики в разрезе их ресурсопотребления. В результате получаем информацию: количество выделяемой памяти, количество вызовов функций, время исполнения и т.д.
Установка XHProf
С марта 2009 года XHprof доступен как пакет , поэтому его установка не составит особого труда. Для Windows пакет не доступен.
# pecl search xhprof
Retrieving data...0%
Matched packages, channel pecl.php.net:
=======================================
Package Stable/(Latest) Local
xhprof 0.9.2 (beta) XHProf: A Hierarchical Profiler for PHP
Т.к. пакет xhprof находится в стадии beta, то нужно разрешить его установку:
Если попытаться установить пакет через PECL, то получим ошибку:
# pecl install xhprof
downloading xhprof-0.9.2.tar ...
Starting to download xhprof-0.9.2.tar (Unknown size)
....................................................................done: 1,506,816 bytes
11 source files, building
running: phpize
Cannot find config.m4.
Make sure that you run '/usr/local/bin/phpize' in the top level source directory of the module
ERROR: `phpize' failed
Поэтому выполняем следующие шаги:
# 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 --with-php-config=/usr/local/bin/php-config
# make
# make install
Installing shared extensions: /usr/local/lib/php/20060613/
# make test
Удалять папку xhprof-0.9.2 не следует, т.к. там содержатся утилиты GUI для визуального представления информации профайлера.
Подключаем модуль xhprof к PHP — редактируем файл php.ini (добавляем в конец файла):
Для папки "/var/tmp/xhprof" должен быть доступ на запись, т.к. туда будут сохраняться результаты профайлинга.
Перезагрузите Apache. При вызове phpinfo() появится информация, что подключен модуль xhprof — значит все работает.
Настройка XHProf UI (GUI)
В пакет XHprof входит очень удобный интерфейс для анализа отчетов профилирования. XHprof позволяет строить отчеты, как в текстовом так и графическом ввиде.
В установочной папке xhprof-0.9.2 Вы найдете папку xhprof_html и xhprof_lib, которые нам понадобятся:
• xhprof_html — доступ к GUI
• xhprof_lib — библиотека для отображения и анализа кода (computing flat profile info, computing diffs, aggregating data from multiple runs, etc.).
Папку xhprof_lib размещаем в /usr/local/share/php/ или /usr/local/lib/php/ в зависимости от ОС. Таким образом будет доступ к библиотеки будет глобальный. В нашем случае получится: /usr/local/share/php/xhprof_lib/. Или как вариант папку xhprof_lib можно положить в наш проект.
В зависимости от того как Вы настроете доступ к GUI xhprof, нужно положить xhprof_html в соответствующее место. К примеру, можно создать субдомен или положить в корень проекта
Небольшой пример использования
В качестве примера взят пример с сайта highload.com.ua:
<?php
function user_array_intersect( $a, $b ) {
$res = array();
foreach ( $a as $k => $v )
{
if ( in_array($v, $b) )
{
$res[] = $v;
}
}
return $res;
}
function execute()
{
$a = range(rand(100, 300), rand(700, 900));
$b = range(rand(100, 300), rand(700, 900));
$r1 = user_array_intersect($a, $b);
$r2 = array_intersect($a, $b);
}
# Инициализируем профайлер - будем считать и процессорное время и потребление памяти
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
# Выполняем "программу"
execute();
# Останавливаем профайлер
$xhprof_data = xhprof_disable();
# Сохраняем отчет и генерируем ссылку для его просмотра
include_once "xhprof_lib/utils/xhprof_lib.php";
include_once "xhprof_lib/utils/xhprof_runs.php";
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test");
# Хост, который Вы настроили ранее на GUI профайлера
echo "Report: http://xhprof/index.php?run=$run_id&source=xhprof_test";
echo "\n";
В этом скрипте мы сравним отличие в эффективности работы встроенной функции array_intersect и ее самописного клона user_array_intersect. После описания функций мы подключили профайлер для генерации и сохранения отчета. Посмотрим на отчет:
Из отчета видно, что эффективность собственной реализации функции array_intersect в два раза меньше встроенной (еще одно напоминание об использовании стандартных средств прежде всего!). Небольшая справка по терминологии отчетов:
• Incl[usive] Time — время, потраченное на функцию и на все функции, вызванные из нее
• Excl[usive] Time — время, потраченное на функцию без учета времени на вложенные функции
На скриншоте показана только часть отчета, кроме этих показателей отчет также содержит статистику по процессорным затратам и использованной памяти.
Графические отчеты
XHprof позволяет строить графические отчеты. Для построения он использует внешний инструмент Graphviz, поэтому убедитесь, что он установлен. Графический отчет вышеуказанного скрипта выглядит так:
Графический отчет позволяет визуально оценить ресурсоемкость каждой функции (красный должен привлечь внимание!). Как видим, в примере самой затратной функцией для ресурсов стала in_array(), которая сама по себе не является проблемой но говорит о плохом техническом решении.
Профилирование production проектов
XHprof позволяет профилировать не только отдельные участки кода но и production проекты. Т.к. профилирование проектов в среде production процесс ресурсоемкий, то главный тут критерий — производительность. И XHprof тут прекрасно справляется, т.к. создан он был именно для таких целей. Во-первых XHprof написан на C, во-вторых имеет ряд настроек:
• Таймер CPU на Linux системах имеет большой оверхед, поэтому разработчики рекомендуют использовать профайлер в режиме «elapsed time + memory»:
<?php
// elapsed time profiling (default) + memory profiling
xhprof_enable(XHPROF_FLAGS_MEMORY);
• Сбор данных профайлера будет весьма точно отражать реальную картину, если его запускать не каждый раз, а случайно и равнораспределенно, например для запуска каждый сотый раз:
<?php
if (mt_rand(1, 100) == 1) {
xhprof_enable(XHPROF_FLAGS_MEMORY);
$xhprof_on = true;
}
...
if ($xhprof_on) {
$xhprof_data = xhprof_disable();
}
• Режим Lightweight Sampling — в этом режиме профилирование выполняется в течении короткого промежутка во времени (сэмплами) — 0.1 секунды
Пример профилирования production проекта
В качестве примера используем проект на Yii — Hello World!
Наш проект
GUI нашего профайлера (содержимое папки xhprof_html)
xhprof_lib находится в "/usr/local/share/php/xhprof_lib".
Создаем 2 файла (header.php и footer.php).
header.php
<?php
if (extension_loaded('xhprof')) {
// Способ 1 - файлы лежат в проекте
// include_once '/usr/local/share/php/xhprof_lib/utils/xhprof_lib.php';
// include_once '/usr/local/share/php/xhprof_lib/utils/xhprof_runs.php';
// Способ 2 - файлы лежат в /usr/local/share/php/xhprof_lib
include_once dirname(__FILE__) . '/xhprof_lib/utils/xhprof_lib.php';
include_once dirname(__FILE__) . '/xhprof_lib/utils/xhprof_runs.php';
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
footer.php
<?php
if (extension_loaded('xhprof')) {
$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)
$profiler_url = sprintf('http://' . $_SERVER['SERVER_NAME'] . '/xhprof/index.php?run=%s&source=%s',
$run_id, $profiler_namespace);
// Можем сделать защиту по айпи, или добавить $_GET параметр
if (in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1')))
{
// На нашей странице появится ссылка "Profiler output",
// которая ведет на GUI XHprof с уникальными идентификатором отчета
echo '
<a href="'. $profiler_url .'" target="_blank">Profiler output</a>';
}
}
Для внедрения профайлера в наш проект есть 2 способа:
<?php
include('xhprof/header.php');
// include Yii bootstrap file
require_once(dirname(__FILE__).'/framework/yii.php');
// create a Web application instance and run
Yii::createWebApplication()->run();
include('xhprof/footer.php');
Загружаем страницу сайта. Внизу страницы появляется ссылка «Profiler output», которая ведет на GUI XHprof с уникальными идентификатором отчета. Каждый раз, когда мы обновляем страницу отчет перегенирируется и идентификатор изменится.
Получаем отчет:
Показатели:
• Total Incl. Wall Time (microsec): 18,710 microsecs (время затраченное на выполнение функций с учетом ожидания ответов от сокетов, файловой системы и других ресурсов )
• Total Incl. CPU (microsecs): 16,309 microsecs (время затраченное на выполнение функций)
• Total Incl. MemUse (bytes): 527,604 bytes (использование памяти)
• Total Incl. PeakMemUse (bytes): 529,428 bytes (пиковое использование памяти)
• Number of Function Calls: 179 (количество вызовов функций)
Они разные, и дают разную информацию. Например: в Xdebug нет такой информации как «Количество вызовов функции». Xdebug — и отладчик и профайлер. Я бы сказал, что они дополняют друг друга :)
Коментарі (3)
RSS згорнути / розгорнутипитання: так що краще xhprof чи xdebug?
zenyk
ingvar
я пробував додавати дебаг php в netbeans. були трошки танці з бубнами :)
от думав чи варто паритись з xhprof :)
zenyk
Тільки зареєстровані й авторизовані користувачі можуть залишати коментарі.