Najprostszy sposób na profilowanie skryptu PHP

Jaki jest najprostszy sposób na profilowanie skryptu PHP?

Chciałbym podkręcić coś, co pokazuje mi zrzut wszystkich wywołań funkcji i jak długo trwały, ale jestem również w porządku z umieszczaniem czegoś wokół konkretnych funkcji.

Próbowałem eksperymentować z funkcjąmicrotime :

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

echo sprintf("Elapsed:  %f", $now-$then);
Ale to czasami daje mi negatywne wyniki. Poza tym jest dużo kłopotów, aby posypać To całym moim kodem.
 263
Author: Mark Biek, 2008-08-22

12 answers

Rozszerzenie PECL APD jest używane w następujący sposób:

<?php
apd_set_pprof_trace();

//rest of the script
?>

Po przetworzeniu wygenerowanego pliku za pomocą pprofp.

Przykładowe wyjście:

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
 102
Author: Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-22 00:46:49

Chcesz xdebug chyba. Zainstaluj go na serwerze, włącz, przepompuj wyjście przez kcachegrind (dla Linuksa) lub wincachegrind (Dla windows) i pokaże Ci kilka ładnych wykresów, które szczegółowo określają dokładne czasy, zliczanie i zużycie pamięci (ale potrzebujesz do tego innego rozszerzenia).

Wymiata, Serio: d

 251
Author: mercutio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 09:20:36

Nie są potrzebne żadne rozszerzenia, wystarczy użyć tych dwóch funkcji do prostego profilowania.

// 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>";
}

Oto przykład, wywołanie prof_flag() z opisem na każdym punkcie kontrolnym i prof_print () na końcu:

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

Wyjście wygląda tak:

Start
0.004303
Połącz z DB
0.003518
wykonaj zapytanie
0.000308
pobieranie danych
0.000009
Zamknij DB
0.000049
zrobione

 76
Author: TimH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 20:45:49

Jeśli odejmowanie mikrotimów daje negatywne wyniki, spróbuj użyć funkcji z argumentem true (microtime(true)). Za pomocą true funkcja zwraca zmiennoprzecinkową zamiast ciągu znaków (jak to ma miejsce, gdy jest wywoływana bez argumentów).

 23
Author: luka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-06 14:22:15

Szczerze mówiąc, zamierzam argumentować, że używanie NewRelic do profilowania jest najlepsze.

Jest to rozszerzenie PHP, które nie wydaje się spowolnić runtime w ogóle i robią monitorowanie za Ciebie, umożliwiając przyzwoite drill down. W drogiej wersji pozwalają na ciężkie drążenie (ale nie stać nas na ich model cenowy).

Mimo to, nawet z darmowym/standardowym planem, jest oczywiste i proste, gdzie większość nisko wiszących owoców jest. Podoba mi się również to, że może dać pomysł na DB interakcje też.

zrzut ekranu jednego z interfejsów podczas profilowania

 21
Author: zeroasterisk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-19 02:13:57

Prześlij moje referencje z Dokumentacji so beta, która przechodzi w tryb offline.

Profilowanie za pomocą XDebug

Rozszerzenie PHP o nazwie Xdebug jest dostępne do pomocy w profilowaniu aplikacji PHP, a także debugowaniu w trybie runtime. Podczas uruchamiania profilera wyjście jest zapisywane do pliku w formacie binarnym o nazwie "cachegrind". Aplikacje są dostępne na każdej platformie do analizy tych plików. żadne zmiany w kodzie aplikacji nie są konieczne do wykonania to profilowanie.

Aby włączyć profilowanie, zainstaluj rozszerzenie i dostosuj php.ustawienia ini. Niektóre dystrybucje Linuksa posiadają standardowe pakiety (np. Pakiet php-xdebug Ubuntu). W naszym przykładzie uruchomimy profil opcjonalnie w oparciu o parametr request. Dzięki temu możemy zachować statyczne ustawienia i włączyć profiler tylko w razie potrzeby.

# 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"

Następnie użyj programu web client, aby wysłać żądanie do adresu URL aplikacji, który chcesz profilować, np.

http://example.com/article/1?XDEBUG_PROFILE=1

Jako strona przetwarza zapis do pliku o nazwie podobnej do

/tmp/cachegrind.out.12345

Domyślnie numer w nazwie pliku jest identyfikatorem procesu, który go zapisał. Jest to konfigurowalne za pomocą ustawienia xdebug.profiler_output_name.

Zauważ, że zapisuje po jednym pliku dla każdego wykonanego żądania / procesu PHP. Tak więc, na przykład, jeśli chcesz przeanalizować post formularza, jeden profil zostanie napisany dla żądania GET, aby wyświetlić formularz HTML. Parametr XDEBUG_PROFILE będzie musiał zostać przekazany do następnego posta żądanie analizy drugiego żądania, które przetwarza formularz. Dlatego podczas profilowania czasami łatwiej jest uruchomić curl, aby bezpośrednio opublikować formularz.

Analiza wyjścia

Po zapisaniu Cache profilu może być odczytany przez aplikację taką jak KCachegrind lub Webgrind. PHPStorm, popularne PHP IDE, może również wyświetlać te dane profilowania.

KCachegrind

KCachegrind, na przykład, wyświetli informacje w tym:

  • funkcje wykonywane
  • Czas wywołania, zarówno sam w sobie, jak i z włączeniem kolejnych wywołań funkcji
  • Liczba razy każda funkcja jest wywoływana
  • wykresy wywołania
  • linki do kodu źródłowego

Czego szukać

Oczywiście dostrajanie wydajności jest bardzo specyficzne dla każdego zastosowania aplikacji. Ogólnie dobrze jest szukać:

  • powtarzane wywołania tej samej funkcji, której nie spodziewałbyś się zobaczyć. Na funkcje Przetwarzające i zapytujące dane mogą to być główne możliwości buforowania aplikacji.
  • wolno działające funkcje. Gdzie aplikacja spędza większość czasu? najlepszą wypłatą w tuningu wydajności jest skupienie się na tych częściach aplikacji, które zużywają najwięcej czasu.

Uwaga: Xdebug, a w szczególności jego funkcje profilowania, są bardzo zasobochłonne i spowalniają wykonywanie PHP. Zaleca się, aby nie uruchamiać ich w produkcji środowisko serwera.

 16
Author: Matt S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 13:06:59

PECL XHPROF wygląda też na interensting. Posiada klikalny interfejs HTML do przeglądania raportów i dość prostą dokumentację . Muszę jeszcze go przetestować.

 10
Author: Josef Sábl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 11:26:12

Lubię używać phpDebug do profilowania. http://phpdebug.sourceforge.net/www/index.html

Wyświetla cały czas / zużycie pamięci dla dowolnego używanego SQL, a także wszystkich dołączonych plików. Oczywiście najlepiej działa na kodzie, który jest abstrakcyjny.

Do profilowania funkcji i klas użyję tylko microtime() + get_memory_usage() + get_peak_memory_usage().

 8
Author: Eric Lamb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-04 19:15:16

Profilowanie biednego człowieka, nie wymaga żadnych rozszerzeń. Obsługuje zagnieżdżone profile i procent całości:

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;
}

Przykład:

<?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
  ]
]
 7
Author: bishop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 20:36:48

Dałbym BlackFire szansę.

Jest taki virtualBox, który stworzyłem używając puphpet, aby przetestować różne frameworki php, które współpracują z BlackFire, prosimy o rozwidlenie i / lub dystrybucję w razie potrzeby:)

Https://github.com/webit4me/PHPFrameworks

 5
Author: Ali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-29 21:04:20

Do benchmarkingu, jak w twoim przykładzie, używam pakietu Pear Benchmarking. Ustawiasz znaczniki do pomiaru. Klasa zapewnia również kilka pomocników prezentacji, lub możesz przetwarzać dane według własnego uznania.

Mam go w innej klasie z metodą _ _ destruct. Kiedy skrypt się kończy, wyjście jest rejestrowane przez log4php do syslog, więc mam wiele danych wydajności do pracy z.

 4
Author: Gary Richardson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-22 15:43:20

XDebug nie jest stabilny i nie zawsze jest dostępny dla konkretnej wersji php. Na przykład na niektórych serwerach nadal uruchamiam php-5.1.6, -- to jest to, co pochodzi z RedHat RHEL5 (a btw nadal otrzymuje aktualizacje dla wszystkich ważnych spraw), a ostatnio Xdebug nawet nie kompiluje się z tym php. Więc skończyło się na przełączeniu na DBG debugger Its PHP benchmarking zapewnia timing dla funkcji, metod, modułów, a nawet linii.

 2
Author: user2221743,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-04 07:48:58