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

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

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

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

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

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

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

12 ответов



вы хотите 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();

вывод выглядит следующим образом:

старт
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

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

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

что искать

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

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

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


PECL XHPROF выглядит слишком interensting. Он имеет кликабельный 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 в syslog, поэтому у меня есть много данных о производительности для работы.


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