XHProf и xDebug - профилирование (profiling) кода PHP

С помощью систем для профилирования можно собрать информацию о том, какие функции в php-коде потребляют больше процессорного времени и оперативной памяти, то есть выявить наиболее медленные и требовательные к памяти места в программе на php.

xhprof

XHProf - PHP profiler разработанный в Facebook.

Установка:

aptitude install php-pear
pecl install xhprof-0.9.4
echo "extension=xhprof.so" > /etc/php5/mods-available/xhprof.ini
ln -s /etc/php5/mods-available/xhprof.ini /etc/php5/conf.d/xhprof.ini
apachectl restart

Необходимые для работы файлы расположены в директории /usr/share/php. Однако не все, а только c php-кодом. Для нормального отображения отчетов требуется jquery и css. Их можно заполучить из репозитория на github:

git clone https://github.com/facebook/xhprof.git

Далее, для сбора данных требуется скопировать директорию xhprof_lib в директорию сайта. Выше уже сообщалось, что данные файлы расположены в директории /usr/share/php.

После этого в код php-скрипта в месте, откуда должен начаться сбор данных добавляем строку:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

В скобках указаны параметры для сбора данных. В данном случае будет осуществляться сбор данных по нагрузке на процессор и по использованию оперативной памяти. Возможен еще один параметр XHPROF_FLAGS_NO_BUILTINS при использовании которого данные по встроенным функциям не собираются.

Далее, в конце php-кода, который будет профилироваться следует добавить:

$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");
echo "Report: http://domain.tld/xhprof_html/index.php?run=$run_id&source=xhprof_test";
echo "\n";

В строке $run_id в кавычках указано название профиля, которое можно задать произвольно.

Название профиля используется в ссылке на страницу с отображением содержимого профиля, которая будет видна на профилируемой странице и которую можно будет скопировать в строку адреса браузера.

По ссылке вида http://domain.tld/xhprof_html/ можно будет получить список адресов на страницы с информацией по созданным ранее профилям.

Результат в обработанном виде выглядит следующим образом:

xhprof со встроенными функциями

Щелкая по ссылкам можно углубиться в цепочки вызовов функций с аналогичной информацией на каждом этапе.

Если указать параметр XHPROF_FLAGS_NO_BUILTINS, то видно, что количество вызовов функций значительно снижается:

xhprof без встроенных функций

В таблице представлена следующая информация:

Calls - количество вызовов функции,
Wall Time - общее время работы функции вклчая время ожидания ответа от внешних ресурсов,
CPU - сколько времени было затарчено на обработку функций,
MemUse - сколько оперативной памяти было задействовано,
PeakMemUse - пиковое потребление памяти.

В качестве модификаторов выступают:

Incl - inclusive - с учетом вызовов других функций из этой функции,
Excl - exclusive - без учета вызовов функций.

Кроме того, над таблицей представлена информация о суммарных времени обработки, использованной памяти и количестве вызовов функций.

Также XHProf позволяет строить разностные отчеты между двумя запусками, которые обозначаются красным и зеленым цветами. С помощью таких отчетов можно получить ясную картину улучшений после каждого изменения кода.

xhprof сравнение профилей

Для получения подобного отчета нужно воспользоваться ссылкой вида:

http://domain.tld/xhprof_html/index.php?run1=run_id1&run2=run_id2&source=xhprof_test

где run_id1 и run_id2 - идентификаторы запусков.

Если установить Graphviz:

aptitude install graphviz

то по ссылке “View Full Callgraph” откроется наглядная схема на которой будут обозначены наиболее долгие вызовы функций и их место в цепочке вызовов:

График в xhprof с помощью graphviz

Также для php profiler xhprof существуют сторонние веб-интерфейсы использующие базы данных:

http://xhprof.io/ - MySQL,
https://github.com/perftools/xhgui - MongoDB.

xDebug

xDebug - дебаггер PHP-кода с возможностью профилирования (profiling), написанный Дериком Ретансом (Derick Rethans).

Установка:

yum install php5-xdebug

Затем редактируем конфиг:

nano /etc/php5/mods-available/xdebug.ini

добавляя в него строки:

xdebug.profiler_enable = 1
xdebug.profiler_aggregate = On
xdebug.profiler_output_dir = /tmp

Здесь включаем PHP профайлер и указываем директорию в которую складывать профили. Профили создаются с именами вида cachegrind.out.*

Существует веб-клиент webgrind: https://github.com/jokkedk/webgrind. Работает он не слишком быстро, но позволяет оперативно просмотреть небольшие профили. Фактически это код на PHP, который нужно склонировать с github:

git clone https://github.com/jokkedk/webgrind.git

создастся директория webgrind, которую нужно скопировать в директорию любого сайта и обратиться к ней из браузера. Далее, чтобы в Debian заработало построение графиков в конфигурационном файле config.php нужно поправить путь до исполняемого файла graphviz. Должно получиться так:

static $dotExecutable = '/usr/bin/dot';

Кроме того, можно подправить часовой пояс:

static $defaultTimezone = 'Europe/Moscow';

Webgrind - веб-интерфейс для профайлера xDebug

В заголовке можно выбрать профиль  и поставить галочку учитывать ли встроенные функции. В самой таблице видны функции, количество вызовов, время работы самой функции и время с учетом ожидания. Чтобы углубиться в функции достаточно щелкнуть по треугольной стрелочке. В моем случае при достаточно объемных профилях (от нескольких мегабайт), ожидание результата было излишне большим. Вероятно, для достаточно крупных профилей лучше использовать локальные программы просмора.

График может выглядеть следующим образом:

График в webgrind с помощью graphviz

Обратите внимание, что webgrind не стоит использовать на производственных серверах, так как какая-либо авторизация не предусмотрена, но при этом есть доступ к коду файлов на php. В случае необходимости используйте хотя бы базовую авторизацию Apache.

Также существуют программы для анализа профилей как под Linux:

http://kcachegrind.sourceforge.net/cgi-bin/show.cgi
https://code.google.com/p/xdebugtoolkit/

так и под Windows:

http://sourceforge.net/projects/wincachegrind/

О профилировании

Данные профиля могут помочь вам улучшить ваше приложение, то есть достичь определенных целей, к примеру, понизить потребление памяти, уменьшить время генерации страницы и так далее.

Информация в профиле является стартовой точкой в оптимизации: сообщается сколько времени генерируется результат, сколько памяти используется и сколько вызовов функций происходит. С помощью более подробных данных вы можете улучшить эти показатели.

К примеру, если вы используете фреймворк, то использование некоторых функций фреймворка может вести к вызову нескольких базовых функций. Если вы читаете некоторые данные несколько раз, то, возможно, стоит сохранить результат в переменную.

Также профайлер может помочь понять где стоит использовать кэширование PHP-кода, к примеру, с помощью APCu или memcached.

Прежде всего, стоит оптимизировать функции, который требуют больше всего времени на исполнение. После того, как все оптимизировано и кажется, что улучшать больше нечего, стоит отсортировать функции по количеству вызовов и поработать над его понижением. Даже если PHP работает быстро, то стоит подумать, нужно ли вызывать функции так часто?

При обнаружении следующих ситуаций стоит подумать о кэшировании:

  • Неизменяемые функции вызываются внутри цикла,
  • Некое содержимое генерируется дважды,
  • Содержимое, которое не изменяется генерируется каждый раз,
  • Содержимое генерируется, даже если не используется.

Не стоит кэшировать все подряд, так как память тоже ценный ресурс. Кэшируйте те данные, к которым обращаетесь постоянно. Также кэширование имеет мало смысла в случае если кэширование тратит больше ресурсов, чем экономит.

Кроме кэширования в коде не стоит забывать о кэшировании с помощью веб-сервера (кэширование в nginx), а также на стороне клиента. Если использовать правильные заголовки, то многие запросы могут быть разрешены еще до поступления на сервер.

Ссылки

http://kurapov.name/rus/technology/web/php/php_profiling/ - об инструментах профилирования на русском,
http://techportal.inviqa.com/2009/12/01/profiling-with-xhprof/ - достаточно подробно о профилировании на английском,
http://pinba.org/ - система мониторинга нагрузки на php-скрипты в реальном времени. Использует MySQL.

Полезные статьи:

Анализ запросов к mysql.
Анализ веб-сервера.

Наверх

Опубликовано