Самый простой способ профилировать скрипт PHP

289

Какой самый простой способ профилировать скрипт PHP?

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

Я попытался поэкспериментировать с функцией microtime :

$then = microtime();
myFunc();
$now = microtime();

echo sprintf("Elapsed:  %f", $now-$then);

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

Марк Бик
источник
7
Эй, Марк, зацени
Мина,
16
Этот комментарий, связанный с @Midiane, не имеет смысла. Если это казалось решением проблемы комментатора, это должно было быть совпадением. Только с помощью microtime()приведет иногда оценивающее выражение , как: "0.00154800 1342892546" - "0.99905700 1342892545", который будет оценивать , как: 0.001548 - 0.999057. Вы можете использовать, microtime( TRUE )чтобы избежать этой проблемы, как указано @luka.
JMM

Ответы:

104

Расширение PECL APD используется следующим образом:

<?php
apd_set_pprof_trace();

//rest of the script
?>

После разбора созданного файла с помощью pprofp.

Пример вывода:

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace

Предупреждение: последний выпуск APD датирован 2004 годом, расширение больше не поддерживается и имеет различные проблемы с совместимостью (см. Комментарии).

Винсент
источник
19
Расширение APD не работает на php 5.4.
Skynet
В ответ на user457015 я смог заставить его работать на веб-сайте, работающем под управлением WordPress 3.8.1 и PHP 5.3.10, и, похоже, он работал нормально.
Сверхновая
1
@Supernovah, пользователь 457015 сказал PHP 5.4. Он не сказал, что это было сломано на PHP 5.3.
Магнус
@ user1420752 У меня работает 5.3.27, и он там тоже не работает. Я получаю неопределенную ошибку функции.
Фрактальная
2
Последний выпуск APD от 2004 года (!). Он не работает с PHP 7. При попытке установить PHP 5 с pecl install apdон выдает сообщение об ошибке «config.m4». Похоже, вы должны установить его из источника, который я еще не пробовал. Серьезно, разве нет современного обновленного инструмента профилирования на основе CLI для PHP, который устанавливается с помощью Homebrew, требует минимальной настройки и дает легко читаемый вывод?
forthrin
267

Вы хотите xdebug, я думаю. Установите его на сервер, включите его, прокачайте вывод через kcachegrind (для linux) или wincachegrind (для windows), и он покажет вам несколько симпатичных диаграмм, которые детализируют точные тайминги, количество и использование памяти (но вы нужно другое расширение для этого).

Это качается, серьезно: D

Меркуцио
источник
6
Я нашел, что это намного легче реализовать, чем решение APD. Но, может быть, это потому, что по какой-то причине APD неправильно скомпилировался в моей системе. Графики kcachegrind были такими же красивыми, как и обещали.
WXS
1
@EvilPuppetMaster, вам нужно скомпилировать php с --enable-memory-limit или использовать более современную версию php. См. Xdebug.org/docs/basic#xdebug_memory_usage
mercutio
52
xdebug + webgrind быстро стали моим любимым оружием для быстрого и простого профилирования. code.google.com/p/webgrind
xkcd150
6
xdebug + xdebug_start_trace () + xdebug_stop_trace () = победа
квано
3
Это было очень легко начать работать на Windows с XAMPP. Уже были настроены netbeans для xdebug. Единственное, что вам нужно сделать, это изменить настройку xdebug в php.ini на xdebug.profiler_output_name = "cachegrind.out.% T-% s", иначе вывод не будет сгенерирован. Требуется перезагрузка apache.
beginner_
97

Расширения не нужны, просто используйте эти две функции для простого профилирования.

// Call this at each point of interest, passing a descriptive string
function prof_flag($str)
{
    global $prof_timing, $prof_names;
    $prof_timing[] = microtime(true);
    $prof_names[] = $str;
}

// Call this when you're done and want to see the results
function prof_print()
{
    global $prof_timing, $prof_names;
    $size = count($prof_timing);
    for($i=0;$i<$size - 1; $i++)
    {
        echo "<b>{$prof_names[$i]}</b><br>";
        echo sprintf("&nbsp;&nbsp;&nbsp;%f<br>", $prof_timing[$i+1]-$prof_timing[$i]);
    }
    echo "<b>{$prof_names[$size-1]}</b><br>";
}

Вот пример, вызывающий prof_flag () с описанием в каждой контрольной точке и prof_print () в конце:

prof_flag("Start");

   include '../lib/database.php';
   include '../lib/helper_func.php';

prof_flag("Connect to DB");

   connect_to_db();

prof_flag("Perform query");

   // Get all the data

   $select_query = "SELECT * FROM data_table";
   $result = mysql_query($select_query);

prof_flag("Retrieve data");

   $rows = array();
   $found_data=false;
   while($r = mysql_fetch_assoc($result))
   {
       $found_data=true;
       $rows[] = $r;
   }

prof_flag("Close DB");

   mysql_close();   //close database connection

prof_flag("Done");
prof_print();

Вывод выглядит так:

Начало
   0,004303
Подключение к БД
   0,003518
Выполнить запрос
   0,000308
Получить данные
   0,000009
Закрыть БД
   0,000049
Готово

TimH - Codidact
источник
37

Перекрестная публикация моей ссылки из SO Documentation beta, которая выходит из сети.

Профилирование с помощью XDebug

Доступно расширение для PHP под названием Xdebug, которое поможет в профилировании PHP-приложений , а также в отладке во время выполнения. При запуске профилировщика выходные данные записываются в файл в двоичном формате с именем «cachegrind». Приложения доступны на каждой платформе для анализа этих файлов. Для выполнения этого профилирования не требуется никаких изменений кода приложения.

Чтобы включить профилирование, установите расширение и настройте параметры php.ini. Некоторые дистрибутивы Linux поставляются со стандартными пакетами (например, php-xdebugпакет Ubuntu ). В нашем примере мы запустим профиль по выбору на основе параметра запроса. Это позволяет нам сохранять настройки статичными и включать профилировщик только по мере необходимости.

# php.ini settings
# Set to 1 to turn it on for every request
xdebug.profiler_enable = 0
# Let's use a GET/POST parameter to turn on the profiler
xdebug.profiler_enable_trigger = 1
# The GET/POST value we will pass; empty for any value
xdebug.profiler_enable_trigger_value = ""
# Output cachegrind files to /tmp so our system cleans them up later
xdebug.profiler_output_dir = "/tmp"
xdebug.profiler_output_name = "cachegrind.out.%p"

Затем используйте веб-клиент для запроса URL-адреса вашего приложения, который вы хотите профилировать, например,

http://example.com/article/1?XDEBUG_PROFILE=1

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

/tmp/cachegrind.out.12345

По умолчанию номер в имени файла является идентификатором процесса, который его написал. Это настраивается с xdebug.profiler_output_nameнастройкой.

Обратите внимание, что он будет записывать один файл для каждого выполняемого запроса / процесса PHP. Так, например, если вы хотите проанализировать публикацию формы, будет написан один профиль для запроса GET для отображения формы HTML. Параметр XDEBUG_PROFILE необходимо будет передать в последующий запрос POST для анализа второго запроса, который обрабатывает форму. Поэтому при профилировании иногда проще запустить curl для POST формы.

Анализируя вывод

После записи кеш профиля может быть прочитан таким приложением, как KCachegrind или Webgrind . PHPStorm, популярная PHP IDE, также может отображать эти данные профилирования .

KCachegrind

KCachegrind, например, будет отображать информацию, включая:

  • Функции выполнены
  • Время вызова, как само по себе, так и с учетом последующих вызовов функций
  • Сколько раз вызывается каждая функция
  • Графики звонков
  • Ссылки на исходный код

Что искать

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

  • Повторные вызовы той же функции, которую вы не ожидаете увидеть. Для функций, которые обрабатывают и запрашивают данные, это может быть основной возможностью для вашего приложения для кэширования.
  • Медленные функции. Где приложение тратит большую часть своего времени? Лучшее преимущество при настройке производительности - это сосредоточение на тех частях приложения, которые занимают больше всего времени.

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

Мэтт С
источник
3
Добавление в список инструментов для разбора кеша профилей: PhpStorm также имеет инструмент для предпросмотра кеша профилей
peterchaula
1
@peter Я забыл, что PHPStorm имеет эту функцию. Я добавил это со ссылкой на документацию. Спасибо!
Мэтт S
Любой способ получить текстовый (не GUI) отчет прямо на сервере?
Александр Щебликин
1
@ Марк, не могли бы вы отметить это как ответ, пожалуйста. Текущий ответ устарел даже после публикации и не работал в течение многих лет. Это работает, и я не знаю лучшего способа.
Mawg говорит восстановить Монику
24

Если вычитание микротрем дает отрицательные результаты, попробуйте использовать функцию с аргументом true( microtime(true)). С trueпомощью функции возвращает число с плавающей точкой вместо строки (как это происходит, если она вызывается без аргументов).

Luka
источник
24

Честно говоря, я собираюсь утверждать, что использование NewRelic для профилирования является лучшим.

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

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

скриншот одного из интерфейсов при профилировании

zeroasterisk
источник
16
Конечно, New Relic выглядит многообещающе. Тем не менее, «Раскрытие ваших данных приложения» часть их Политики конфиденциальности оттолкнуло меня сразу. Имхо, делиться частями закрытого исходного кода с третьими сторонами - это слишком много.
Ченгиз может
8
Здесь не прыгать в защиту, но похоже, что «Данные приложения» - это просто информация о производительности и конфигурации системы, а не исходный код вашего приложения.
Дэвид Шилдс
Во-первых, моя новая реликвия показывает мою «WebTransaction» как 99% времени, и у меня нет профессионального аккаунта для «ApplicationTraces»
Karthik T
1
попробуйте зарегистрироваться по адресу: newrelic.com/rackspace <должен дать вам "стандарт" бесплатно
zeroasterisk
16

Профилирование бедного человека, никаких расширений не требуется. Поддерживает вложенные профили и процент от общего:

function p_open($flag) {
    global $p_times;
    if (null === $p_times)
        $p_times = [];
    if (! array_key_exists($flag, $p_times))
        $p_times[$flag] = [ 'total' => 0, 'open' => 0 ];
    $p_times[$flag]['open'] = microtime(true);
}

function p_close($flag)
{
    global $p_times;
    if (isset($p_times[$flag]['open'])) {
        $p_times[$flag]['total'] += (microtime(true) - $p_times[$flag]['open']);
        unset($p_times[$flag]['open']);
    }
}

function p_dump()
{
    global $p_times;
    $dump = [];
    $sum  = 0;
    foreach ($p_times as $flag => $info) {
        $dump[$flag]['elapsed'] = $info['total'];
        $sum += $info['total'];
    }
    foreach ($dump as $flag => $info) {
        $dump[$flag]['percent'] = $dump[$flag]['elapsed']/$sum;
    }
    return $dump;
}

Пример:

<?php

p_open('foo');
sleep(1);
p_open('bar');
sleep(2);
p_open('baz');
sleep(3);
p_close('baz');
sleep(2);
p_close('bar');
sleep(1);
p_close('foo');

var_dump(p_dump());

Урожайность:

array:3 [
  "foo" => array:2 [
    "elapsed" => 9.000766992569
    "percent" => 0.4736904954747
  ]
  "bar" => array:2 [
    "elapsed" => 7.0004580020905
    "percent" => 0.36841864946596
  ]
  "baz" => array:2 [
    "elapsed" => 3.0001420974731
    "percent" => 0.15789085505934
  ]
]
епископ
источник
13

PECL XHPROF тоже выглядит интересно. Он имеет интерактивный HTML-интерфейс для просмотра отчетов и довольно простой документации . Я все еще должен проверить это все же.

Йозеф Сабл
источник
Похоже, что он не получает много любви. Последнее обновление в 2009 году, нет пакетов PEAR для 5.3, 5.4 и выше ...
dland
1
Facebook создал форк с поддержкой php 5.5 github.com/facebook/xhprof
borkencode
Также проверьте этот
ответвление,
xhprof.io предоставляет графический интерфейс для данных, собранных с помощью XHProf, а также возможность хранить данные в базе данных для целей исторического анализа. Я являюсь автором последней реализации.
Gajus
10

Мне нравится использовать phpDebug для профилирования. http://phpdebug.sourceforge.net/www/index.html

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

Для функции и класса профилирования я буду использовать microtime()+ get_memory_usage()+ get_peak_memory_usage().

Эрик Лэмб
источник
7

Я бы демонстративно дал попробовать BlackFire .

Есть этот VirtualBox, который я собрал, используя puphpet , для тестирования различных php-фреймворков, которые совместимы с BlackFire, пожалуйста, не стесняйтесь раскошелиться и / или распространять при необходимости :)

https://github.com/webit4me/PHPFrameworks

Али
источник
6

Для бенчмаркинга, как в вашем примере, я использую пакет Pearl Benchmark . Вы устанавливаете маркеры для измерения. Класс также предоставляет несколько помощников для презентаций, или вы можете обрабатывать данные по своему усмотрению.

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

Гари Ричардсон
источник
3

XDebug нестабилен и не всегда доступен для конкретной версии php. Например, на некоторых серверах я все еще использую php-5.1.6 - это то, что поставляется с RedHat RHEL5 (а btw все еще получает обновления по всем важным вопросам), а недавний XDebug даже не компилируется с этим php. В итоге я переключился на отладчик DBG. Его тестирование php обеспечивает синхронизацию функций, методов, модулей и даже строк.

user2221743
источник
2

Вы все должны обязательно проверить этот новый профилировщик php.

https://github.com/NoiseByNorthwest/php-spx

Он переопределяет способ сбора профилировщиков php и представляет результат. Вместо того, чтобы выводить только общее количество вызовов конкретной функции и общее время, потраченное на ее выполнение, PHP-SPX представляет всю временную шкалу выполнения запроса в удобочитаемой форме. Ниже приведен экран графического интерфейса, который он предоставляет.

введите описание изображения здесь

Яцек Дзюрдзиковски
источник