Вопрос:

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

php profiling

171323 просмотра

13 ответа

93263 Репутация автора

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

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

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

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

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

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

Автор: Mark Biek Источник Размещён: 21.08.2008 08:40

Ответы (13)


8 плюса

896 Репутация автора

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

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

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

Автор: Eric Lamb Размещён: 21.08.2008 08:45

257 плюса

12116 Репутация автора

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

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

Автор: mercutio Размещён: 21.08.2008 08:46

104 плюса

10810 Репутация автора

Решение

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

Автор: Vincent Размещён: 21.08.2008 09:04

4 плюса

10671 Репутация автора

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

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

Автор: Gary Richardson Размещён: 22.08.2008 03:43

10 плюса

3852 Репутация автора

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

Автор: Josef Sábl Размещён: 23.06.2011 11:26

23 плюса

272 Репутация автора

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

Автор: luka Размещён: 10.01.2012 04:47

2 плюса

87 Репутация автора

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

Автор: user2221743 Размещён: 04.04.2013 07:48

21 плюса

1829 Репутация автора

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

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

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

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

Автор: zeroasterisk Размещён: 19.12.2013 02:05

83 плюса

1092 Репутация автора

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

// 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 Размещён: 12.03.2015 11:43

5 плюса

2055 Репутация автора

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

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

https://github.com/webit4me/PHPFrameworks

Автор: Ali Размещён: 29.09.2015 09:04

9 плюса

24653 Репутация автора

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

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
  ]
]
Автор: bishop Размещён: 07.09.2016 08:36

25 плюса

11382 Репутация автора

Перекрестная публикация моей ссылки из 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. Рекомендуется не запускать их в рабочей среде сервера.

Автор: Matt S Размещён: 04.08.2017 05:27

0 плюса

11 Репутация автора

Попробуйте liveprof . Это инструмент, который объединяет результаты профилирования и показывает историю производительности.

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

Автор: Timur Shagiakhmetov Размещён: 22.03.2019 01:46
Вопросы из категории :
32x32