Сведения о вопросе

CPdeveloper

03:57, 1st August, 2020

Теги

php   profiling    

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

Просмотров: 600   Ответов: 12

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

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

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

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

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

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



  Сведения об ответе

FAriza

04:12, 1st August, 2020

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

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


  Сведения об ответе

+-*/

04:22, 7th August, 2020

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


  Сведения об ответе

pumpa

01:29, 19th August, 2020

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

// 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
Подключение к DB
   0.003518
Выполнить запрос
   0.000308
Извлечь данные
   0.000009
Рядом DB
   0.000049
Сделано



  Сведения об ответе

DO__IT

04:26, 1st August, 2020

Кросс-постинг моей ссылки из бета-версии SO Documentation, которая собирается в автономном режиме.

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

KCachegrind

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

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

На что обратить внимание

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

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

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


  Сведения об ответе

repe

16:38, 12th August, 2020

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


  Сведения об ответе

DAAA

13:21, 8th August, 2020

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

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

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

screenshot of one of the interfaces when profiling


  Сведения об ответе

lesha

08:22, 26th August, 2020

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


  Сведения об ответе

nYU

07:34, 15th August, 2020

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

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


  Сведения об ответе

9090

03:14, 29th August, 2020

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

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

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


  Сведения об ответе

lool

22:10, 22nd August, 2020

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

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

https://github.com/webit4me/PHPFrameworks


  Сведения об ответе

lesha

20:02, 10th August, 2020

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

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


  Сведения об ответе

FAriza

11:17, 22nd August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться