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



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



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



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



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

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


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

573   12  

12 ответов:

The PECL APD

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

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

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

// 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();

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

Start
0.004303
подключение к DB
0.003518
выполнить запрос
0.000308
извлечь данные
0.000009
закрыть DB
0.000049
сделал

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

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

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

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

screenshot of one of the interfaces when profiling

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

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

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

чтобы включить профилирование, установите расширение и настройте php.параметры ini. Некоторые дистрибутивы Linux поставляются со стандартными пакетами (например, 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 для публикации формы напрямую.

анализ производства

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

KCachegrind

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

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

что искать

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

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

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

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

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

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

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

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

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

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

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

https://github.com/webit4me/PHPFrameworks

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

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

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

Comments

    Ничего не найдено.