Profilownie kodu w Pythonie oraz Django
- Opublikowano November 12, 2007
- komentarze 0
Ostatnio chciałem sprofilować moją aplikacje w Django. Postanowieniem przyjrzeć się tej kwestii. W Pythonie od wersji 2.2 w bibliotece standardowej jest profiler kodu HotShot(High performance logging profiler) Jest on zamiennikiem istniejącego we wcześniejszych wersjach Pythona modułu Profile. Moduł HotShot jest interface'em do modułu _hotshot z C, dzięki temu temu jest dużo szybszy niż stary moduł Profile i daje bardziej precyzyjne wyniki.
Przykład profilowanie dowolnego kodu z pomocą modułu HotShot:
Profilowanie funkcji moja_funkcja:
import hotshot def moja_funkcja(): j = 0 for i in range(1,10000): j += i return j if __name__ == '__main__': prof = hotshot.Profile("mojprofil.prof") prof.run("moja_funkcja()") prof.close()
Metoda Profile stworzy plik w którym zostaną zapisane statystki profilowania. Można także pomiędzy dowolny kod wstawić gdzie ma zacząć sie profilowanie a gdzie skończyć:
import hotshot prof = hotshot.Profile("mojprofil.prof") prof.start() # ...tutaj kod który ma zostać sprofilowany... prof.stop() prof.close()
Drukowanie wyników:
import hotshot.stats stats = hotshot.stats.load("mojprofil.prof") stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(20)
2 function calls in 0.004 CPU seconds
Ordered by: internal time, call count
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.004 0.004 0.004 0.004 profile_test.py:3(moja_funkcja)
1 0.000 0.000 0.004 0.004 :1()
0 0.000 0.000 profile:0(profiler)
W zwróconym wyniku mamy następujące parametry:
- ncalls
- Ilość wywołań funkcji/metody
- tottime
- Całkowity czas wykonań danej funkcji wykluczając inne pod funkcje.
- percall
- Czas wykonania pojedynczej funkcji.
- cumtime
- Całkowity czas wykonania wszystkich funkcji o tej samej nazwie łącznie z innymi pod funkcjami które wywołuje ta funkcja.
- percall
- Czas wykonania pojedynczej funkcji, wraz z pod funkcjami, które wywołuje ta funkcja.
- filename:lineno(function)
- nazwa pliku:nr_linii(funkcja)
Tutaj można znaleźć dekorator który umożliwia, oznaczenie danej funkcji czy metody aby była sprofilowana
Wygenerowane wyniki można także zobaczyć w postaci graficznej, potrzebny jest do tego program kcachegrind dostępny pod linux'em. Nie znalazłem jakiegoś odpowiednika pod Windows'a, podobno można go uruchomić pod Windows'em z pomocą Cygwina, ale nie sprawdzałem bo używam Ubuntu, zarówno w pracy jak i w domu. Aby zobaczyć graficzne wyniki profilowania trzeba je skonwertować do formatu obsługiwanego przez kcachegrind. Potrzebny do tego jest pakiet kcachegrind-converters. Po zainstalowaniu pakietu wykonujemy polecenie hotshot2calltree nasz_plik_z_profilem > cachegrind.out.01.
Jeżeli chodzi profilowanie Django to istnieje kilka możliwości. Django posiada hander django.core.handlers.profiler-hotshot który umożliwia profilowanie widoków gdy używa się mod_pythona, druga możliwość to uruchomienie django przez serwer WSGI. Dokładny opis można znaleźć tutaj. Najbardziej ciekawy i elegancki sposób jaki znalazłem to profilowanie django za pomocą middleware'a dostępnego tutaj. Wystarczy dopisać go na początek listy middlewre'ów naszej aplikacji w settings.py. Aby z profilować dowolny widok wystarczy dopisać na koniec url'a ?prof. Np.
http://mojadomena.com/mojwidok/?prof.
Po wywołaniu takiego widoku na ekranie otrzymamy statystyki profilowania.