Профилирование PHP-приложений
с помощью PhpStorm и Xdebug
Это руководство описывает профилирование PHP-приложений с помощью PhpStorm и Xdebug. Если ты предпочитаешь использовать Zend Debugger, смотри Профилирование PHP-приложений с помощью PhpStorm и Zend Debugger.
Используя PhpStorm, ты можешь проанализировать работу своего PHP кода профилируя его. Профилирование позволит тебе собрать статистику выполнения программы: имена выполняемых функций, сколько раз каждая функция была выполнена, время выполнения каждой функции, какие другие функции были вызваны внутри каждой функции и так далее.
Эта информация может дать тебе подсказку о том, где твой код может быть улучшен.
Давай посмотрим, как это работает.
1. Необходимые условия
IDE PhpStorm может использовать информацию профилирования собранную с помощью инструмента Xdebug. Это расширение должно быть установлено и настроено в твоей системе. Для получения дополнительной информации смотри Руководство по установке Xdebug.
Если ты являешься пользователем замечательной портативной серверной платформы и программной среды Open Server, то делать ничего ненадо — расширение Xdebug уже установлено и подключено.
Xdebug не совместим с IonCube. IonCube — это инструмент (утилиты) для защиты ПО, написанного на языке программирования PHP. Отключи расширение IonCube совсем или на время использования Xdebug. Ещё одна вероятная проблема может состоять в том, что Xdebug по умолчанию настроен на порт 9000 и он же используется в Open Server. Для её решения следует в одном из случаев изменить номер порта.
Все действия, описанные здесь, были воспроизведены с корректными ожидаемыми результатами при следующем технологическом окружении:
2. Включение профайлера Xdebug
Профилирование добавляет некоторые накладные расходы на запуск приложения и генерирует огромное количество информации на диске. Поэтому, лучше всего, включать профайлер Xdebug только при необходимости и отключать в обычных условиях.
Конфигурирование Xdebug осуществляется через директивы в активном php.ini файле. При любом способе включения профайлера необходимо настроить следующую директиву:
В значении директивы необходимо указать путь, который будет использоваться для сохранения файлов профилирования.
2.1. В глобальном масштабе
Чтобы включить профайлер Xdebug в глобальном масштабе необходимо использовать нижеуказанную директиву:
Таким образом профилирование будет осуществляться при каждом запуске любого сценария. Использовать данный вариант включения профайлера удобно лишь в редких случаях.
2.2. С помощью дополнительных параметров интерпретатора
Включить профайлер с помощью дополнительных параметров интерпретатора можно в окне Run/Debug Configurations. Для его открытия используй следующие пункты главного меню IDE: [Run → Edit Configurations...]
Опция (отмечена красным контуром на скриншоте выше) Interpreter options (параметры интерпретатора) секции Command Line (командная строка) должна содержать следующую строку:
Такой вариант позволит тебе использовать профайлер для конкретной конфигурации, а не в глобальном масштабе.
2.3. С помощью специальных GET/POST параметров или cookie файла
Для более управляемого профилирования необходимо использовать нижеуказанную директиву:
Если значение директивы установлено в 1, то при выполнении сценария с GET/POST параметром или кукой с именем XDEBUG_PROFILE профилирование будет выполнено вне зависимости от установки xdebug.profiler_enable.
Данный вариант включения профайлера самый популярный.
Для удобства профилирования по требованию лучше используй букмарклеты для PhpStorm или одно из расширений браузера для отладки.
3. Сбор логов профилирования
Для получения возможности анализа логов профилирования их необходимо сначала собрать.
3.1. Сбор логов профилирования для веб-приложений
Для профилирования веб-приложений используй профайлер Xdebug глобально или запускай и останавливай его по требованию. После включения профайлера открой приложение в браузере, чтобы начать сбор данных — логов профилирования.
При анализе проблем производительности, использование букмарклетов или расширений браузера для отладки является очень хорошим подходом, так как позволяет перемещаться по приложению и запускать профайлер только в тот момент, когда обнаружена проблема производительности. Это позволяет собирать целевые логи профилирования.
3.2. Сбор логов профилирования для CLI приложений и юнит-тестов
Для профилирования CLI приложений и юнит-тестов используй профайлер Xdebug глобально или создай отдельную конфигурацию запуска для включения профайлера с помощью окна Run/Debug Configurations. После чего запускай CLI приложение или юнит-тесты для сбора данных профилирования.
При анализе проблем производительности в юнит-тестах хорошим подходом является создание отдельной конфигурации запуска только тех юнит-тестов, в которых есть подозрения на проблемы с производительностью. Это позволяет собирать целевые логи профилирования.
4. Анализ описания лога профилирования
Давай подробнее рассмотрим лог профилирования.
4.1. Открытие лога профилирования
Для открытия лога профилирования используй следующие пункты главного меню IDE: [Tools → Analyze Xdebug Profiler Snapshot...].
Если ты являешься пользователем замечательной портативной серверной платформы Open Server, то для просмотра лога профилирования также можешь использовать кроссплатформенный инструмент Webgrind. Его можно найти через следующие пункты главного меню Open Server [Дополнительно → PHP профайлер].
Логи профилирования сохраняются в папку согласно настроенной директиве xdebug.profiler_output_dir. Имя генерируемого файла всегда начинается с cachegrind.out. и заканчивается либо идентификатором процесса PHP или процесса веб-сервера или crc32 хэшем каталога, в котором находится профилируемый сценарий.
4.2. Вкладка Execution Statistics
Во вкладке Execution Statistics (статистика выполнения) ты можешь изучить сводную информацию о метриках исполнения каждой вызываемой функции. Ты можешь увидеть все файлы, вызовы функций, сколько раз они были вызваны, и время (абсолютное и относительное) выполнения каждой функции.
В верхней сетке отображаются различные метрики:
- Callable (вызванный файл) — файл, который был выполнен.
- Time (время) — общее время выполнения.
- Own Time (собственное время) — количество времени, которое функция затрачивает на выполнение своего кода (без учёта вызова других функций).
- Calls (вызовы) — количество вызовов.
В нижней сетке отображаются две вкладки: Callees (вызываемые) — функции, которые сценарий вызывает здесь и Callers (вызывающие) — откуда сценарий был вызван. Ты можешь видеть различные метрики и здесь:
- Callable (вызванная функция) — функция, которая была выполнена.
- Time (время) — общее время выполнения.
- Calls (вызовы) — количество вызовов.
Функции с большим собственным временем выполения или большим количеством вызовов, безусловно, требуют проверки.
4.3. Вкладка Call Tree
Во вкладке Call Tree (дерево вызовов) отображаются пути выполнения твоего кода. Тут ты можешь увидеть более подробную информацию о времени выполнении каждой функции и так далее.
В верхней сетке отображаются деревья вызовов (какие функции вызываются в других функциях) и другие метрики:
- Callable (вызванный файл) — файл, который был выполнен.
- Time (время) — общее время выполнения.
- Calls (вызовы) — количество вызовов.
В нижней сетке отображаются две вкладки: Callees (вызываемые) — функции, которые вызываются здесь и Callers (вызывающие) — откуда вызывается функция. Ты можешь видеть различные метрики и здесь:
- Callable (вызванная функция) — функция, которая была выполнена.
- Time (время) — общее время выполнения.
- Calls (вызовы) — количество вызовов.