Jak porównać wydajność skryptu PHP

133

Chcę wiedzieć, jaki jest najlepszy sposób testowania moich skryptów PHP. Nie ma znaczenia, czy jest to zadanie cron, strona internetowa czy usługa internetowa.

Wiem, że mogę używać microtime, ale czy to naprawdę daje mi rzeczywisty czas działania skryptu PHP?

Chcę przetestować i porównać różne funkcje w PHP, które robią to samo. Na przykład preg_matchvs strposlub domdocumentvs preg_matchlub preg_replace vs str_replace`

Przykład strony internetowej:

<?php
// login.php

$start_time = microtime(TRUE);

session_start(); 
// do all my logic etc...

$end_time = microtime(TRUE);

echo $end_time - $start_time;

To wyświetli: 0,0146126717 (zmienia się przez cały czas - ale to ostatnie, które otrzymałem). Oznacza to, że wykonanie skryptu PHP zajęło 0,015 lub więcej.

Czy jest lepszy sposób?

eric
źródło
Przeczytaj ten artykuł: rakesh.sankar-b.com/2011/01/12/echo-print-which-is-fast-php - mam nadzieję, że to pomoże.
Rakesh Sankar
4
0,015 sekundy. Średnia prędkość mrugania oka wynosi 0,3 sekundy. Czy naprawdę, naprawdę, naprawdę potrzebujesz poprawić tę prędkość, czy mogę zapytać dlaczego?
Ben
4
@ben to przykład, mam strony, które ładują się w 0,8 sekundy z ponad 50 000 odwiedzających na godzinę. Muszę się upewnić, że strona ładuje się szybko
eric
8
@MarcB Amazon najwyraźniej przetestował i stwierdził, że opóźnienie 100 ms spowodowało 1% spadek sprzedaży. To mogą być miliardy w przypadku dużej witryny, takiej jak Amazon. highscalability.com/…
ceejayoz
1
@ceejayoz Tak, jeśli jesteś amazonem, to jest to duży problem, ale jeśli nie, to uważaj, aby po prostu ścigać szalone czasy ładowania strony ze względu na to. Amazon odrobił swoją pracę domową i dlatego może z łatwością uzasadnić spędzenie X godzin roboczych, aby odzyskać Y spadek sprzedaży. Lekcja tutaj polega na samodzielnym odrabianiu pracy domowej!
James Butler

Odpowiedzi:

124

Jeśli faktycznie chcesz porównać kod ze świata rzeczywistego, użyj narzędzi takich jak Xdebug i XHProf .

Xdebug jest świetny do pracy w środowisku deweloperskim / przejściowym, a XHProf jest świetnym narzędziem do produkcji i można go tam bezpiecznie uruchamiać (o ile przeczytasz instrukcje). Wyniki ładowania jednej strony nie będą tak istotne, jak sprawdzenie, jak działa Twój kod, gdy serwer jest zmuszany do wykonania miliona innych rzeczy, a zasoby stają się ograniczone. To rodzi kolejne pytanie: czy masz wąskie gardło na procesorze? BARAN? I / O?

Musisz także spojrzeć poza kod, który uruchamiasz w swoich skryptach, na sposób, w jaki Twoje skrypty / strony są obsługiwane. Z jakiego serwera WWW korzystasz? Jako przykład mogę sprawić, że nginx + PHP-FPM poważnie przewyższy wykonanie mod_php + Apache, który z kolei zostaje odrzucony do obsługi statycznej zawartości za pomocą dobrego CDN.

Następną rzeczą do rozważenia jest to, pod kątem czego próbujesz zoptymalizować?

  • Czy szybkość, z jaką strona renderuje się w przeglądarce użytkownika, jest priorytetem numer jeden?
  • Czy celem jest jak najszybsze odrzucanie każdego żądania do serwera przy jak najmniejszym zużyciu procesora?

Pierwszemu można pomóc, robiąc takie rzeczy, jak zgzowanie wszystkich zasobów wysłanych do przeglądarki, ale może to (w niektórych okolicznościach) odciągnąć cię od osiągnięcia drugiego.

Miejmy nadzieję, że wszystkie powyższe mogą pomóc wykazać, że starannie odizolowane testy „laboratoryjne” nie będą odzwierciedlać zmiennych i problemów, które napotkasz na produkcji, i że musisz określić, jaki jest twój cel na wysokim poziomie, a następnie co możesz zrobić, aby go osiągnąć, przed wyruszeniem w drogę mikro / przedwczesnej optymalizacji do piekła .

James Butler
źródło
7
Jeśli to naprawdę odpowiada na twoje pytanie eric, czuję, że twoje pytania zostały sformułowane nieprawidłowo (a może po prostu źle je odczytałem). Opierając się na twoim pytaniu, brzmiało to tak, jakbyś chciał wyodrębnić różne metody robienia tego samego w PHP i określić, która z nich jest najszybsza. Jednak na podstawie odpowiedzi, które zaakceptowałeś i przyznałeś nagrodę, wydaje się, że bardziej interesowało Cię wykonanie testów obciążenia całego stosu internetowego - co jest czymś zupełnie innym.
Alec Gorge
Xdebug nie obsługuje skryptów zakodowanych w Ioncube. Jak oceniasz ten scenariusz?
BigSack
@BigSack Jesteś tam trochę sam, nigdy nie próbowałem profilować niczego, co jest tak zaciemnione. Najpierw miałbym strzał z XHProf, ponieważ jest to stosunkowo łatwe do uruchomienia. Może się okazać, że IonCube całkowicie ingeruje w każdy profiler spoza przestrzeni użytkownika.
James Butler,
1
Instrukcja Nginx vs Apache jest nieco stronnicza. Większość zaniedbuje AllowOveridezmuszanie Apache do przeszukiwania całych katalogów w poszukiwaniu plików .htaccess przy każdym żądaniu. Samo to usuwa Apache z własnej drogi.
B00MER
75

Aby porównać szybkość działania całego skryptu na serwerze, można skorzystać z wielu narzędzi. Najpierw upewnij się, że twój skrypt (na przykład preg_match vs strpos) musi generować te same wyniki, aby zakwalifikować twój test.

Możesz użyć:

Księga Zeusa
źródło
31

Będziesz chciał przyjrzeć się Xdebug, a dokładniej możliwościom profilowania Xdebug .

Zasadniczo włączasz profiler i za każdym razem, gdy ładujesz stronę internetową, tworzy on plik cachegrind, który można odczytać za pomocą WinCacheGrind lub KCacheGrind .

Xdebug może być nieco trudny do skonfigurowania, więc tutaj jest odpowiednia sekcja mojego w php.inicelach informacyjnych:

[XDebug]
zend_extension = h:\xampp\php\ext\php_xdebug-2.1.1-5.3-vc6.dll
xdebug.remote_enable=true
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=h:\xampp\cachegrind
xdebug.profiler_output_name=callgrind.%t_%R.out

A oto zrzut ekranu .outpliku w WinCacheGrind :

wprowadź opis obrazu tutaj

Powinno to dostarczyć wielu informacji na temat wydajności skryptu PHP. Chcesz kierować reklamy na rzeczy, które zajmują najwięcej czasu. Na przykład możesz zoptymalizować jedną funkcję tak, aby zajmowała połowę czasu, ale twoje wysiłki byłyby lepiej wykorzystane, optymalizując funkcję, która nazywa się dziesiątki, jeśli nie setki razy podczas ładowania strony.

Jeśli jesteś ciekawy, to tylko stara wersja CMS, którą napisałem na własny użytek.

Alec Gorge
źródło
8
wydają się bardzo skomplikowane, nic nie rozumiem
eric
Której części nie rozumiesz? Konfiguracja czy analiza danych?
Alec Gorge
1
no cóż, konfiguracja nie, to nigdy nie będzie działać na moim serwerze, ale dane, to wszystkie małe pudełka, których nie mogę odczytać
eric
14
ponieważ nie używam systemu Windows
eric
2
+1 dla XDebug + KCacheGrind. Jest naprawdę pomocny i zaskakująco łatwy w instalacji i obsłudze. Używam go od dłuższego czasu, dodatkowy bonus, który otrzymujesz - jeden, który go znasz, możesz użyć KCacheGrind z Valgrind (+ memgrind / callgrind), aby profilować znacznie więcej innych języków (i nie tylko czasu procesora).
XzKto
16

Wypróbuj https://github.com/fotuzlab/appgati

Pozwala zdefiniować kroki w kodzie i raportuje czas, zużycie pamięci, obciążenie serwera itp. Między dwoma krokami.

Coś jak:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

Przykładowa tablica wyjściowa:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)
fotuzlab
źródło
2
Piękny projekt interfejsu (jak widzę, że jesteś autorem), gratulacje! (I dzięki za użycie "ProperCase";) nazwy metod (jak SetMemory()) zamiast brzydkich, ale wciąż wszechobecnych mixedCase()bzdur, co i tak jest praktycznie bezcelowe w PHP. Prawdopodobnie jesteś za stara. ;))
Sz.
1
Całkowicie przestarzały, ale w ciągu kilku minut zmieniłem go w coś fajnego i użytecznego (nawet w oknach). Spróbuję sprawdzić, czy mogę złożyć wniosek o ściągnięcie.
Tomas Gonzalez
7

Zajrzałbym do xhprof . Nie ma znaczenia, czy jest uruchamiany w CLI, czy za pośrednictwem innego sapi (np. Fpm lub fcgi lub nawet modułu Apache).

Najlepsze w xhprof jest to, że jest wystarczająco sprawny, aby można go było uruchomić w produkcji. Coś, co nie działa tak dobrze z xdebug (ostatnio sprawdzałem). xdebug ma wpływ na wydajność, a xhprof (nie powiedziałbym, że go nie ma) radzi sobie dużo lepiej.

Często używamy xhprof do zbierania próbek z rzeczywistym ruchem, a następnie analizowania stamtąd kodu.

To naprawdę nie jest punkt odniesienia, jeśli chodzi o to, że daje ci czas i tak dalej, chociaż to też robi. Ułatwia to po prostu analizę ruchu produkcyjnego, a następnie przejście do poziomu funkcji php w zebranym callgraph.

Po skompilowaniu i załadowaniu rozszerzenia rozpoczynasz profilowanie w kodzie za pomocą:

xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

Zatrzymać:

$xhprof_data = xhprof_disable();

Następnie zapisz dane do pliku lub bazy danych - cokolwiek unosi Twoją łódź i nie przerywa zwykłego działania. Asynchronicznie przekazujemy to do S3, aby scentralizować dane (aby móc zobaczyć wszystkie przebiegi ze wszystkich naszych serwerów).

Kod na github zawiera xhprof_html folder, który można zrzucić na serwerze i przy minimalnej konfiguracji można wizualizować dane zebrane i rozpocząć wiercenie w dół.

HTH!

Do
źródło
3

Umieść to w forpętli, aby wykonać każdą czynność 1000000 razy, aby uzyskać bardziej realistyczną liczbę. I tylko uruchamiaj licznik czasu tuż przed kodem, który chcesz przetestować, a następnie zapisz czas zakończenia tuż po (tj. Nie uruchamiaj licznika czasu przed session_start().

Upewnij się również, że kod jest identyczny dla każdej funkcji, którą chcesz przetestować, z wyjątkiem funkcji, której czas jest przeznaczony.

Sposób wykonywania skryptu (cronjob, php z wiersza poleceń, Apache itp.) Nie powinien mieć znaczenia, ponieważ mierzysz tylko względną różnicę między szybkością różnych funkcji. Więc ten stosunek powinien pozostać taki sam.

Jeśli na komputerze, na którym uruchamiasz test porównawczy, dzieje się wiele innych rzeczy, może to wpłynąć na wyniki testu, jeśli zdarzy się, że podczas działania testu porównawczego nastąpi wzrost wykorzystania procesora lub pamięci przez inną aplikację. Ale dopóki masz dużo zasobów do zaoszczędzenia na komputerze, nie sądzę, że będzie to problem.

Alasdair
źródło
1

Na dobry początek skorzystaj z xdebugs profiler http://xdebug.org/docs/profiler

Może nie jest to najłatwiejsza rzecz w konfiguracji i obsłudze, ale kiedy już ją uruchomisz, ogromne ilości danych i łatwość przeglądania są niezastąpione.

Koza
źródło
0

Eric,

Zadajesz sobie złe pytanie. Jeśli twój skrypt wykonuje się w ~ 15 msek, to jego czas jest w dużej mierze nieistotny. Jeśli uruchomisz usługę udostępnioną, aktywacja obrazu PHP zajmie ~ 100 ms, odczyt plików skryptów ~ 30-50 ms, jeśli jest w pełni buforowany na serwerze, prawdopodobnie 1 lub więcej sekund, jeśli jest ładowany z farmy NAS zaplecza. Opóźnienia sieciowe podczas ładowania mebli strony mogą dodać wiele sekund.

Głównym problemem jest postrzeganie czasu ładowania przez użytkowników: jak długo musi czekać między kliknięciem linku a wyświetleniem w pełni wyrenderowanej strony. Zapoznaj się z Google Page Speed, którego możesz używać jako rozszerzenia Ff lub Chrome, oraz dokumentacji Pagespeed, która szczegółowo omawia, jak uzyskać dobrą wydajność strony. Postępuj zgodnie z tymi wskazówkami i postaraj się uzyskać wyniki stron lepsze niż 90/100. (Strona główna google ma 99/100, podobnie jak mój blog). To najlepszy sposób na uzyskanie dobrej wydajności postrzeganej przez użytkowników.

TerryE
źródło
0

Dobrze jest również mieć oko na swój kod PHP i sprawdzić go za pomocą tego linku , aby upewnić się, że samo kodowanie nie zakłóca wydajności aplikacji.

Ritesh Aryal
źródło