Найпростіший спосіб профілювання PHP-скрипту


289

Який найпростіший спосіб профілювати сценарій PHP?

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

Я спробував експериментувати з функцією мікрочасу :

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

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

але це іноді дає мені негативні результати. Плюс - це багато клопоту посипати це по всьому моєму коду.


7
ей Марк, ознайомтеся з цим коментарем, щоб допомогти вам вирішити негативні коментарі: ro.php.net/manual/en/function.microtime.php#99524
Міна

16
Цей коментар, пов’язаний з @Midiane, не має сенсу. Якщо здавалося, що це вирішило проблему коментатора, це, мабуть, був збігом обставин. Тільки з допомогою microtime()призведе іноді оцінює вираз , як: "0.00154800 1342892546" - "0.99905700 1342892545", який буде оцінювати , як: 0.001548 - 0.999057. Ви можете використовувати, microtime( TRUE )щоб уникнути цієї проблеми, на що вказував @luka.
JMM

Відповіді:


104

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


19
Розширення APD розбито на php 5.4.
Скайнет

Якщо повернутись до user457015, мені вдалося змусити його працювати на веб-сайті, на якому працюють Wordpress 3.8.1 та PHP 5.3.10, і, здавалося, він працює добре.
Супернова

1
@Supernovah, user457015 сказав PHP 5.4. Він не сказав, що його зламали на PHP 5.3.
магнус

@ user1420752 Я працюю 5.3.27, і він також не працює. Я отримую невизначену помилку функції.
Fractaly

2
Останній реліз APD - це з 2004 року (!), Він не працює з PHP 7. При спробі встановити для PHP 5 pecl install apd, він видає повідомлення про помилку про "config.m4". Схоже, вам доведеться встановити його з джерела, чого я ще не пробував. Серйозно, чи не існує сучасного оновленого CLI-інструменту для профілювання PHP, який встановлюється за допомогою Homebrew, вимагає мінімальних налаштувань і дає можливість легко читати результат?
1616

267

Ви хочете, xdebug я думаю. Встановіть його на сервер, увімкніть його, перекачайте вихід через kcachegrind (для Linux) або wincachegrind (для windows), і він покаже вам декілька гарних діаграм, що деталізують точні терміни, підрахунки та використання пам'яті (але ви для цього потрібне інше розширення).

Він хитається, серйозно: D


6
Мені це було набагато простіше здійснити, ніж рішення APD. Але, можливо, це тому, що чомусь APD не скомпілюється належним чином у моїй системі. Також графіки kcachegrind були такими ж гарними, як і обіцяли.
wxs

1
@EvilPuppetMaster, вам потрібно скомпілювати php з --enable-memory-limit або використовувати більш сучасну версію php. Дивіться xdebug.org/docs/basic#xdebug_memory_usage
mercutio

52
xdebug + webgrind швидко став моєю зброєю вибору для швидкого та простого профілювання. code.google.com/p/webgrind
xkcd150

6
xdebug + xdebug_start_trace () + xdebug_stop_trace () = win
quano

3
Це було дуже легко отримати роботу в Windows з XAMPP. Вже були налаштовані netbeans для xdebug. Єдине, що вам потрібно зробити - це змінити параметр xdebug у php.ini на xdebug.profiler_output_name = "cachegrind.out.% T-% s", інакше не буде створено жодного результату. Потрібен перезапуск апаша.
початківець_

97

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

// 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
Закрити DB
   0,000049
Готово


37

Перехресне розміщення моєї посилання з бета-документації SO Documentation, яка переходить в офлайн.

Профілювання за допомогою 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. Рекомендується не запускати їх у виробничому сервері.


3
Додавання до списку інструментів для розбору кешів профілю: PhpStorm також має інструмент для попереднього перегляду кеш-профілю
peterchaula

1
@peter Я забув, що PHPStorm має таку особливість. Я додав його із посиланням на документацію. Дякую!
Метт С

Будь-який спосіб отримати текстовий (не-GUI) звіт безпосередньо на сервері?
Олександр Щеблікін

1
@Марк, чи можете ви позначити це як відповідь, будь ласка. Поточна відповідь застаріла навіть при опублікуванні та не працювала протягом багатьох років. Це спрацює, і я не знаю кращого методу.
Мауг каже, що повернемо Моніку

24

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


24

Чесно кажучи, я хочу стверджувати, що використання NewRelic для профілювання є найкращим.

Це розширення PHP, яке, схоже, зовсім не сповільнює час виконання, і вони здійснюють моніторинг за вами, дозволяючи пристойну деталізацію. У дорогій версії вони дозволяють сильно знизити рівень (але ми не можемо дозволити їх модель ціни).

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

скріншот одного з інтерфейсів під час профілювання


16
Нова Реліквія виглядає багатообіцяючо, точно. Однак "Розголошення даних про ваші заявки" частина їх Політики конфіденційності мене негайно відхилила. Імхо, обмін частинами власного вихідного коду з третіми сторонами - це занадто багато.
Cengiz Can

8
Тут не стрибає їх захист, але схоже, що "Дані програми" - це лише інформація про продуктивність та інформація про конфігурацію системи, а не вихідний код програми.
Девід Шилдс

Я бачу, що моя нова реліквія показує мою "Веб-трансакцію" як 99% часу, і не маю профільного рахунку для "ApplicationTraces"
Karthik T

1
спробуйте зареєструватися за адресою: newrelic.com/rackspace <повинен дати вам "стандарт" безкоштовно
zeroasterisk

16

Профілювання бідного чоловіка, розширення не потрібно. Підтримує вкладені профілі та відсоток від загальної кількості:

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

13

PECL XHPROF також виглядає інтересним. Він має інтерактивний HTML-інтерфейс для перегляду звітів та досить простої документації . Я все ще маю це перевірити.


Схоже, це не отримує великої любові. Останнє оновлення в 2009 році, без пакетів PEAR для
версій

1
Facebook створив вилку з підтримкою через php 5.5 github.com/facebook/xhprof
borkencode

Перевірте також цю вилку, яка пропонує додаткові коригування: github.com/preinheimer/xhprof
Fedir RYKHTIK

xhprof.io забезпечує графічний інтерфейс для даних, зібраних за допомогою XHProf, а також можливість зберігати дані в базі даних для цілей історичного аналізу. Я є автором останньої реалізації.
Гаджус

10

Мені подобається використовувати phpDebug для профілювання. http://phpdebug.sourceforge.net/www/index.html

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

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


7

Я б заперечно віддав BlackFire спробу спробувати.

Є цей віртуальний бокс, який я зібрав за допомогою лялечки , для тестування різних фрейм-фреймів, які входять із BlackFire, будь ласка, сміливо роздрібнюйте та / або розповсюджуйте, якщо потрібно :)

https://github.com/webit4me/PHPFrameworks


6

Для порівняльного аналізу, як у вашому прикладі, я використовую грушу Benchmark . Ви встановлюєте маркери для вимірювання. У класі також є кілька помічників для презентації, або ви можете обробляти дані так, як вважаєте за потрібне.

Насправді я загорнутий в інший клас методом __destruct. Коли сценарій закінчується, вихід записується через log4php в syslog, тому у мене є багато даних про продуктивність, з яких можна працювати.


3

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


2

Ви всі обов'язково повинні перевірити цей новий php-профайл.

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

Він переосмислює спосіб того, як PHP-профілі збирає та представляє результат. Замість того, щоб виводити лише загальну кількість викликів функцій та загальний час, витрачений на її виконання - PHP-SPX представляє всю часову шкалу виконання запиту ідеально читабельним чином. Нижче показаний екран GUI, який він надає.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.