profiling

Z zagadnieniem profilowania kodu, każdy programista spotyka się prędzej czy później. Przychodzi bowiem taki moment, w którym okazuje się, iż napisany przez nas komponent działa zbyt wolno, skutecznie obniżając wydajność całej aplikacji. Z pomocą dla programistów PHP przychodzą liczne narzędzia. Wybrany z nich (Xdebug), postaram się w sposób przystępny i zrozumiały zaprezentować w niniejszym wpisie. Zacznijmy jednak od teorii.

prawo amdahla

Na początku mamy skrypt, który działa zbyt wolno. Po dokonaniu szczegółowej analizy okazuje się że:

  • 80 % czasu jego wykonywania zajmuje „proces autoryzacji”
  • 10 % czasu jego wykonywania zajmuje „logowanie zdarzeń”
  • 10 % czasu jego wykonywania zajmują „operacje arytmetyczne”

Który fragment należy poddać optymalizacji, aby uzyskać maksymalny wzrost wydajności? Na to pytanie udziela nam odpowiedzi prawo Amdahla. Choć wykorzystywane głównie w obliczeniach równoległych, to i dla operacji sekwencyjnych przedstawia algorytm postępowania. Dzięki zastosowaniu kilku prostych wzorów, możemy łatwo określić, jakie działania przyniosą najlepsze rezultaty. Poniżej ukazuję najważniejszy z nich (im wyższy wynik, tym lepsza optymalizacja):

wzor

Gdzie:

  • p – fragment kodu przyspieszony p-razy
  • f – czas wykonywania fragmentu kodu (nieulegającego poprawkom) przed podjęciem jakichkolwiek działań (f należy do przedziału obustronnie otwartego (0,1) )

Warto sprawdzić powyższy wzór w praktyce. Hipotetycznie przyjmijmy więc, że dla skryptu o którym była mowa na początku tego wpisu, mamy następujące możliwości poprawy jego wydajności.

  • 1. proces autoryzacji (80%) może przebiegać dwa razy szybciej
  • 2. operacje arytmetyczne (10%) mogą być wykonywane 100 razy szybciej

Choć stukrotny wzrost może robić duże wrażenie, to po podstawieniu danych do formuły i wykonaniu niezbędnych obliczeń wszystko staje się jasne:

  • rozwiązanie pierwsze ~ 1,6 (p=2, f=1-0.8, f=0.2)
  • rozwiązanie drugie ~ 1,1(p=100, f=1-0.1, f=0.9)

Wybór jest oczywisty – optymalizacja procesu autoryzacji. Czasami podejmowanie decyzji jest trudniejsze, gdyż do wzrostu szybkości dochodzi jeszcze jeden czynnik – nakład pracy. Warto o nim pamiętać, przed dokonaniem ostatecznego wyboru.

xdebug

Profilery najczęściej prezentują dane w dwóch postaciach: tabelarycznej lub / i graficznej. Xdebug pozwala przeanalizować skrypty z wykorzystaniem drugiej formy. Po pomyślnej instalacji potrzebna jest jego szybka konfiguracja (dla zainteresowanych pełna dokumentacja znajduje się TUTAJ).


php.ini
xdebug.profiler_enable=On
xdebug.profiler_output_dir="C:\Users\moje_konto\Desktop"

Pierwsza dyrektywa aktywuje opcję profilera. Druga określa katalog, gdzie wyniki jego pracy mają być zapisywane. Aby je odczytać w zależności od posiadanego systemu operacyjnego potrzebujemy odpowiedni program. Dla Linux’a jest to Kcachegrind (oferuje szerszą gamę funkcjonalności w stosunku do swojego okienkowego konkurenta), a dla Windows’a WinCachegrind. Format tworzonych przez xdebug’a logów przedstawia się następująco: cachegrind.out.xx, gdzie xx to id procesu. Oczywiście nazewnictwo można zmienić, poprzez odpowiednie ustawienie opcji xdebug.profiler_output_name.

Zbytnio nie zwlekając przejdźmy od teorii do praktyki. Poniżej zamieszczam prosty przykład, którego wykonywanie rozłożymy na czynniki pierwsze z użyciem WinCachegrind’a.

function a () {

	$m = 0;
	for ($i=0;$i<1000;++$i)
		$m += 1;

}

function b () {

	$m = 0;
	for ($i=0;$i<10000;$i++)
		$m += 1;

}

a();
b();

Po otwarciu wygenerowanego przez profiler pliku (czyli na dobrą sprawę po uruchomieniu skryptu) naszym oczom ukaże się następujący widok:

Jak na dłoni widać ilości oraz czasy wywołań poszczególnych funkcji, dając nam spore źródło wiedzy niezbędnej do przeprowadzenia efektywnej optymalizacji skryptu.

Proszę traktować ten wpis jako wstęp do zagadnienia jakim jest profilowanie kodu. Osoby zainteresowane pogłębieniem wiedzy w tym zakresie, odsyłam do zapoznania się z takim narzędziem jak XHProf.

5 Odpowiedzi : “profiling”

  1. Dobre, choć krótkie wprowadzenie do profilowania. Choć prawdą jest, że dobre wprowadzenie wymagałoby kilkunastu takich artykułów – może jakaś seria? :-) Chętnie dodam coś od siebie…

  2. Ralf napisał:

    Zgadzam się. Profilowanie to temat rzeka. Co do serii, to po okresie wakacyjnym odezwę się w tej sprawie.

  3. Dzięki wielkie :) . Bardzo fajna i przydatna rzecz :D . Tak z ciekawości: 100 ms na wykonanie się skryptu to dużo czy mało :D ? Wiem, że to głupie pytanie, bo zależy od stopnia zaawansowania… Ale jestem ciekawy Waszej opinii :D . Czy taki skrypt można spokojnie „wypuścić”, czy trzeba optymalizować?

  4. Ralf napisał:

    Zależy co robi ów skrypt. Jeśli wypisuje tylko jakiś string na wyjściu to dużo ;)

  5. Nie spodziewałem się, że tak niewielka różnica w kodzie ma tak wielkie przełożenie na czas jego wykonywania. w tym przypadku 10-krotna!

Pozostaw Odpowiedź