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

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

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

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

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

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

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

Привет, Марк, ознакомьтесь с этим комментарием, чтобы помочь вам решить негативные комментарии: ro.php.net/manual/en/function.microtime.php#99524

Mina 08.03.2012 14:59

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

JMM 21.07.2012 22:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
303
2
192 146
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

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

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

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

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

Это круто, серьезно: D

Я обнаружил, что это намного проще реализовать, чем решение APD. Но, возможно, это потому, что по какой-то причине APD не скомпилировался должным образом в моей системе. Также графики kcachegrind были такими красивыми, как и было обещано.

wxs 05.12.2008 19:23

привет, меркуцио, какое именно расширение позволяет использовать память в xdebug cachegrinds? Я хоть убей не могу заставить это работать.

EvilPuppetMaster 19.02.2009 02:21

@EvilPuppetMaster, вам нужно скомпилировать php с --enable-memory-limit или использовать более современную версию php. См. xdebug.org/docs/basic#xdebug_memory_usage

mercutio 19.02.2009 19:29

xdebug + webgrind быстро стал моим любимым оружием для быстрого и легкого профилирования. code.google.com/p/webgrind

xkcd150 27.04.2010 15:32

xdebug + xdebug_start_trace () + xdebug_stop_trace () = победа

quano 09.05.2011 15:24

Это было очень легко заставить работать в Windows с XAMPP. Уже настроили netbeans для xdebug. Единственное, что вам нужно сделать, это изменить параметр xdebug в php.ini на xdebug.profiler_output_name = "cachegrind.out.% T-% s", иначе вывод не будет создан. Требуется перезапуск apache.

beginner_ 27.09.2012 15:45

Это должен быть лучший / принятый ответ. У меня ушло полчаса, чтобы все заработало (с компиляцией xdebug из исходников). Твердый совет.

Mike Starov 18.07.2014 00:13

Я думаю, что использую qcachegrind для windows. Я пробовал webgrind, но он никогда не загружает даже небольшие файлы. Просто говорит "загрузка" навсегда.

Buttle Butkus 15.10.2015 05:43

Есть ли способ получить текстовый отчет (без графического интерфейса) прямо на сервере?

Alexander Shcheblikin 28.12.2018 15:08

Если вы не используете KDE, вы можете вместо этого использовать qcachegrind, если у вас уже установлен qt. Для меня это была установка 20 МБ против 3 МБ.

ram4nd 07.01.2019 14:55
Ответ принят как подходящий

Расширение 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 годом, расширение больше не поддерживается и имеет различные проблемы совместимости (см. Комментарии).

Расширение APD не работает на php 5.4.

Skynet 25.01.2013 00:59

В ответ на user457015, я смог заставить его работать на веб-сайте, на котором запущены Wordpress 3.8.1 и PHP 5.3.10, и, похоже, он работал нормально.

Supernovah 02.03.2014 17:48

@Supernovah, user457015 сказал, что PHP 5.4. Он не сказал, что это было сломано на PHP 5.3.

magnus 23.10.2015 02:24

@ user1420752 Я использую версию 5.3.27, и она тоже не работает. Я получаю ошибку неопределенной функции.

Fractaly 13.08.2016 21:24

Последний выпуск APD выпущен в 2004 году (!) Он не работает с PHP 7. При попытке установить для PHP 5 с pecl install apd выдает сообщение об ошибке «config.m4». Похоже, вам нужно установить его из исходников, чего я еще не пробовал. Серьезно, разве не существует современного, обновленного инструмента профилирования на основе интерфейса командной строки для PHP, который устанавливается вместе с Homebrew, требует минимальной настройки и дает легко читаемый вывод?

forthrin 29.08.2016 09:38

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

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

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

Похоже, он не получает особой любви. Последнее обновление в 2009 году, нет пакетов PEAR для 5.3, 5.4 и более поздних версий ...

dland 02.02.2013 23:23

Facebook создал форк с поддержкой php 5.5 github.com/facebook/xhprof

borkencode 09.02.2013 01:54

Также проверьте эту вилку, которая предлагает некоторые дополнительные настройки: github.com/preinheimer/xhprof

Fedir RYKHTIK 04.04.2013 19:20
xhprof.io provides GUI for data collected using XHProf, as well as ability to store data in the database for historical analysis purposes. I am the author of the latter implementation.
Gajus 22.02.2014 20:25

Похоже, некоторые детали были обновлены. Во-первых, pecl теперь упоминает, что домашняя страница проекта находится по адресу github, и она активно обновляется. Это расширение будет генерировать данные профилирования, но для их визуализации требуется другой пакет. Я тестирую это и обновлю здесь графический интерфейс, необходимый для этого.

Tuhin 21.12.2020 13:47

Я тестирую инструмент с графическим интерфейсом от github.com/perftools/xhgui, так как он предоставляет образ докера, который легче установить и запустить в кратчайшие сроки. но есть еще один инструмент, на который ссылается php.net: github.com/preinheimer/xhprof

Tuhin 21.12.2020 14:09

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

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

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

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

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

screenshot of one of the interfaces when profiling

New Relic, конечно же, выглядит многообещающе. Однако часть их Политика конфиденциальности «Раскрытие данных вашего приложения» мгновенно оттолкнула меня. Имхо, делиться частями исходного кода проприетарный с третьими сторонами - это слишком.

Cengiz Can 31.03.2014 15:42

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

David Shields 09.05.2014 17:24

Fir моя новая реликвия показывает мою "WebTransaction" как 99% времени, и у меня нет профессиональной учетной записи для "ApplicationTraces"

Karthik T 09.06.2014 17:45

попробуйте зарегистрироваться по адресу: newrelic.com/rackspace

zeroasterisk 10.06.2014 00:58

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

8ctopus 03.11.2020 13:23

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

// 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
RBR_11

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

Вот этот виртуальный бокс, который я собрал с помощью щенок, чтобы протестировать различные php-фреймворки, которые работают с BlackFire, пожалуйста, не стесняйтесь разветвлять и / или распространять, если требуется :)

https://github.com/webit4me/PHPFrameworks

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

Tuhin 21.12.2020 12:56

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

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
  ]
]

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

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

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

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

# 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, также может отобразить эти данные профилирования.

KCachegrind

KCachegrind, например, отобразит такую ​​информацию, как:

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

Что искать

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

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

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

Добавление в список инструментов для анализа кеша профиля: PhpStorm также имеет инструмент для предварительного просмотра кеша профиля.

peterchaula 19.09.2018 14:13

@peter Я забыл, что у PHPStorm есть эта функция. Добавил со ссылкой на документацию. Спасибо!

Matt S 19.09.2018 16:08

Есть ли способ получить текстовый отчет (без графического интерфейса) прямо на сервере?

Alexander Shcheblikin 28.12.2018 15:05

@Mark, пожалуйста, отметьте это как ответ. Текущий ответ устарел, даже когда был опубликован, и не работал много лет. Это работает, и я не знаю лучшего метода.

Mawg says reinstate Monica 12.01.2020 10:58

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

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

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

Удивительный! Просто удивительно!

Xavi Montero 03.08.2020 01:45

мне нравится, насколько просто это было настроить

Lucas Pottersky 27.10.2020 01:49

Это интересно, так как я впервые услышал об этом инструменте. Когда я пытался настроить его на Mac, запуск команды make выдает ошибку not targets specified and no makefile found. так что нужно копать еще немного, чтобы решить эти проблемы.

Tuhin 21.12.2020 13:26

Другие вопросы по теме