— это сбор характеристик работы программы, используемый для анализа ее быстродействия и потребления ресурсов с целью дальнейшей оптимизации
Профайлеры дают возможность оценить:
тратятся ресурсы при выполнении программы
Вряд ли. Оптимизация цельного приложения без профилирования – это догадки и тыканье пальцем в небо.
apt-get install php-xdebug
pecl install xhprof-beta
wget http://pecl.php.net/get/xhprof-0.9.4.tgz
tar xvf xhprof-0.9.4.tgz
cd xhprof-0.9.4/extension
phpize
./configure --with-php-config=/usr/bin/php-config
make
make install
Законфижить в php.ini
[xhprof]
extension=xhprof.so
xhprof.output_dir="/tmp/xhprof"
Включить в коде
<?php
xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
(new Application())->run();
$xhprof_data = xhprof_disable();
Каждый вызов описан так:
["yii\base\Module::runAction==>yii\base\Controller::runAction"] =>
array(5) {
["ct"] => int(1)
["wt"] => int(6718)
["cpu"] => int(6720)
["mu"] => int(617624)
["pmu"] => int(672904)
}
ct
– количество вызовов функцииwt
– реальное время выполнения, микросекундcpu
– процессорное время, микросекундmu
– потребление памяти, байтpmu
– пиковое потребление памяти, байт
<?php
xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
(new Application())->run();
$xhprof_data = xhprof_disable();
$XHPROF_LIB_ROOT = "/opt/xhprof/xhprof_lib";
include_once $XHPROF_LIB_ROOT . "/utils/xhprof_lib.php";
include_once $XHPROF_LIB_ROOT . "/utils/xhprof_runs.php";
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, 'my_application');
Эти PHP файлики можно выкачать из репозитория XHprof и положить в проект, чтобы не зависить от окружения. А еще их можно модифицировать*
Берем директории xhprof_lib
и xhprof_html
из того-же
репозитория,
кладём их рядом, и поднимаем веб-сервер, указывая root в xhprof_html
.
Зная ID профайлов, можно сравнить два запуска:
http://xhprof.localhost/index.php?run1=__ID1__&run2=__ID2__
apt-get install graphviz
Нажимаем на ссылку [View Full Callgraph] на странице просмотра профайла и получаем...
Рисовалка собирает блоки на PHP, можно немного поковырять и добавить вывод нужной инфы, вроде CPU или RAM
tideways-daemon
выгружает собранные профайлы на tideways.ioНа сайте есть мануалы для всех вариантов.
tideways-daemon
можно не ставить, если не планируете пользоваться UI
Законфижить в php.ini
[tideways]
extension=tideways.so
tideways.auto_prepend_library=0
;Закомментировать строку выше, если хотите сливать профайлы на Tideways
Включить в коде
<?php
tideways_enable(TIDEWAYS_FLAGS_CPU | TIDEWAYS_FLAGS_MEMORY | TIDEWAYS_FLAGS_NO_SPANS);
(new Application())->run();
$xhprof_data = tideways_disable();
xhprof_enable() | → | tideways_enable() |
xhprof_disable() | → | tideways_disable() |
XHPROF_FLAGS_CPU | → | TIDEWAYS_FLAGS_CPU |
XHPROF_FLAGS_* | → | XHPROF_FLAGS_* |
<?php
tideways_enable(TIDEWAYS_FLAGS_CPU | TIDEWAYS_FLAGS_MEMORY | TIDEWAYS_FLAGS_NO_SPANS);
(new Application())->run();
$xhprof_data = tideways_disable();
include_once '../xhprof/xhprof_lib.php';
include_once '../xhprof/xhprof_runs.php';
$xhprof_runs = new XHProfRuns_Default('/tmp/xhprof');
$run_id = $xhprof_runs->save_run($xhprof_data, 'my_application');
Для работы стандартного просмотрщика профайлов XHprof нужно сделать
ini_set('xhprof.output_dir', '/your/path')
или найти в исходниках
создание объекта new XHProfRuns_Default('/your/path')
и передать
путь явно
composer require tideways/profiler:*
<?php
\Tideways\Profiler::start(array(
'api_key' => 'YOUR API KEY',
));
(new Application())->run();
Либо настроить автовыгрузку в конфиге PHP или конфиге Apache/Nginx/FPM.
Примеры есть в документации.
И не забыть tideways-daemon
<?php
public function foo()
{
$span = \Tideways\Profiler::createSpan('sql');
$span->startTimer();
$span->annotate(array('title' => 'insert users'));
$this->pdo->query('INSERT INTO users (id, name) values (1, "foo")');
$span->stopTimer();
}
Выключил XDebug
blackfire --samples 10 run php my-script.php
Yii::beginProfile('Checking my new algo');
$system->compute();
Yii::endProfile('Checking my new algo');
fxp/composer-asset-plugin
::className()
в пользу ::class
MaskedInput
, PJAX
из ядра