Jak można profilować skrypt Pythona?

Projekt Euler i inne konkursy kodowania często mają maksymalny czas na uruchomienie lub ludzie chwalą się, jak szybko działa ich konkretne rozwiązanie. W Pythonie, czasami podejścia są nieco kludgey - to znaczy, dodanie kodu czasowego do __main__.

Jaki jest dobry sposób na profilowanie, ile czasu zajmuje uruchomienie programu w Pythonie?

Author: Peter Mortensen, 2009-02-24

29 answers

Python zawiera profiler o nazwie cProfile . Nie tylko podaje całkowity czas pracy, ale także razy każdą funkcję osobno i mówi, ile razy każda funkcja została wywołana, co ułatwia określenie, gdzie należy dokonać optymalizacji.

Możesz wywołać go z kodu lub z interpretera, w następujący sposób:

import cProfile
cProfile.run('foo()')

Jeszcze bardziej użyteczne, można wywołać cProfile podczas uruchamiania skryptu:

python -m cProfile myscript.py

Aby było jeszcze łatwiej, zrobiłem trochę plik wsadowy o nazwie 'profil."bat": {]}

python -m cProfile %1

Więc wszystko co muszę zrobić to uciekać:

profile euler048.py

I rozumiem to:

1007 function calls in 0.061 CPU seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.061    0.061 <string>:1(<module>)
 1000    0.051    0.000    0.051    0.000 euler048.py:2(<lambda>)
    1    0.005    0.005    0.061    0.061 euler048.py:2(<module>)
    1    0.000    0.000    0.061    0.061 {execfile}
    1    0.002    0.002    0.053    0.053 {map}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler objects}
    1    0.000    0.000    0.000    0.000 {range}
    1    0.003    0.003    0.003    0.003 {sum}

EDIT: zaktualizowany link do dobrego źródła wideo z PyCon 2013 zatytułowanego Profilowanie Pythona
również za pośrednictwem YouTube .

 1465
Author: Chris Lawlor,
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-06-26 02:56:06

Jakiś czas temu zrobiłem pycallgraph który generuje wizualizację z kodu Pythona. Edit: zaktualizowałem przykład do pracy z 3.3, najnowszym wydaniem od tego pisania.

Po pip install pycallgraph i zainstalowaniu GraphViz można go uruchomić z linii poleceń:

pycallgraph graphviz -- ./mypythonscript.py

Lub możesz profilować poszczególne części kodu:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()

Każdy z nich wygeneruje pycallgraph.png Plik podobny do poniższego obrazka:

Tutaj wpisz opis obrazka

 450
Author: gak,
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
2019-01-07 05:02:10

Warto zauważyć, że korzystanie z profilera działa tylko (domyślnie) w głównym wątku i nie otrzymasz żadnych informacji z innych wątków, jeśli ich użyjesz. Może to być trochę przykre, ponieważ jest to całkowicie nie wymienione w dokumentacji profilera.

Jeśli chcesz również profilować wątki, będziesz chciał spojrzeć na threading.setprofile() Funkcja W dokumentach.

Możesz również utworzyć własnąthreading.Thread podklasę, aby to zrobić:

class ProfiledThread(threading.Thread):
    # Overrides threading.Thread.run()
    def run(self):
        profiler = cProfile.Profile()
        try:
            return profiler.runcall(threading.Thread.run, self)
        finally:
            profiler.dump_stats('myprofile-%d.profile' % (self.ident,))

I użyj tej klasy ProfiledThread zamiast standardowego. Może to dać ci większą elastyczność, ale nie jestem pewien, czy warto, zwłaszcza jeśli używasz kodu innych firm, który nie używałby twojej klasy.

 210
Author: Joe Shaw,
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
2014-03-15 17:01:53

Python wiki to świetna strona do profilowania zasobów: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

Podobnie jak python docs: http://docs.python.org/library/profile.html

[9]}Jak pokazał Chris Lawlor cProfile jest świetnym narzędziem i może być łatwo użyty do drukowania na ekranie:
python -m cProfile -s time mine.py <args>

Lub do pliku:

python -m cProfile -o output.file mine.py <args>

PS> Jeśli używasz Ubuntu, upewnij się, że zainstalowałeś python-profile

apt-get install python-profiler 

Jeśli wypisz do plik można uzyskać ładne wizualizacje za pomocą następujących narzędzi

PyCallGraph: narzędzie do tworzenia obrazów wykresów wywołania
zainstaluj:

 pip install pycallgraph

Run:

 pycallgraph mine.py args

Widok:

 gimp pycallgraph.png

możesz użyć co chcesz, aby wyświetlić plik png, użyłem gimp
Niestety często dostaję

Kropka: wykres jest zbyt duży dla bitmap renderujących cairo. Skalowanie o 0.257079 aby dopasować

Co sprawia, że moje obrazy są niezwykle małe. Więc generalnie tworzę svg pliki:

pycallgraph -f svg -o pycallgraph.svg mine.py <args>

PS > upewnij się, że zainstalowałeś graphviz (który dostarcza program dot):

pip install graphviz

Alternatywne wykresy przy użyciu gprof2dot przez @ maxy /@quodlibetor:

pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
 161
Author: brent.payne,
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
2020-02-16 20:12:55

Komentarz@Maxy do Ta odpowiedź pomogła mi na tyle, że myślę, że zasługuje na własną odpowiedź: miałem już cProfile-wygenerowane .pliki pstats i nie chciałem ponownie uruchamiać rzeczy z pycallgraph, więc użyłem gprof2dot i dostałem ładne svgs:

$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg

I BLAM!

Używa kropki (tego samego co pycallgraph), więc wyjście wygląda podobnie. Mam wrażenie, że gprof2dot traci jednak mniej informacji: {]}

Przykładowe wyjście gprof2dot

 141
Author: quodlibetor,
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
2020-06-08 08:35:31

Kiedy badałem ten temat, natknąłem się na przydatne narzędzie o nazwie SnakeViz. SnakeViz to internetowe narzędzie do wizualizacji profilowania. Jest bardzo łatwy w instalacji i obsłudze. Zwykle używam go do generowania pliku stat z %prun , a następnie do analizy w SnakeViz.

Główną techniką viz jest Wykres Sunburst Jak pokazano poniżej, w którym hierarchia wywołań funkcji jest ułożona jako warstwy łuków i informacji o czasie zakodowanych w ich szerokościach kątowych.

The best thing czy możesz wchodzić w interakcje z wykresem. Na przykład, aby powiększyć można kliknąć na łuk, a Łuk i jego potomkowie zostaną powiększeni jako nowy sunburst, aby wyświetlić więcej szczegółów.

Tutaj wpisz opis obrazka

 90
Author: zaxliu,
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-05-25 08:06:13

Najprostszy i najszybszy sposób, aby znaleźć, dokąd zmierza cały czas.

1. pip install snakeviz

2. python -m cProfile -o temp.dat <PROGRAM>.py

3. snakeviz temp.dat

Rysuje wykres kołowy w przeglądarce. Największym elementem jest funkcja problemu. Bardzo proste.

 88
Author: CodeCabbie,
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
2020-01-08 09:17:10

cProfile świetnie nadaje się do profilowania, podczas gdy kcachegrind jest świetny do wizualizacji wyników. Na pyprof2calltree pomiędzy obsługuje konwersję plików.

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree
Aby zainstalować wymagane narzędzia (przynajmniej na Ubuntu):
apt-get install kcachegrind
pip install pyprof2calltree

Wynik:

Zrzut ekranu wyniku

 66
Author: Federico,
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
2020-09-22 12:25:42

Niedawno stworzyłem tuna do wizualizacji runtime Pythona i importowania profili; może to być pomocne tutaj.

Tutaj wpisz opis obrazka

Zainstaluj za pomocą

pip install tuna

Utwórz profil runtime

python3 -m cProfile -o program.prof yourfile.py
W tym celu należy skontaktować się z Działem obsługi klienta.]}
python3 -X importprofile yourfile.py 2> import.log

Następnie po prostu uruchom tuna na pliku

tuna program.prof
 46
Author: Nico Schlömer,
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
2020-04-15 09:58:23

Warto również wspomnieć o przeglądarce zrzutu cProfile GUI RunSnakeRun. Pozwala sortować i wybierać, powiększając w ten sposób odpowiednie części programu. Rozmiary prostokątów na zdjęciu są proporcjonalne do czasu. Jeśli najedziesz myszką na prostokąt, podświetli to wywołanie w tabeli i wszędzie na mapie. Po dwukrotnym kliknięciu prostokąta przybliża się on do tej części. Pokaże ci, kto nazywa tę część i co ta część telefony.

Informacje opisowe są bardzo pomocne. Pokazuje kod dla tego bitu, który może być pomocny, gdy masz do czynienia z wbudowanymi wywołaniami biblioteki. Mówi ci, jaki plik i w jakiej linii znaleźć kod.

Chcę również wskazać, że OP powiedział "profilowanie", ale wygląda na to, że miał na myśli "czas". Należy pamiętać, że programy będą działać wolniej po profilowaniu.

Tutaj wpisz opis obrazka

 41
Author: Pete,
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-02-25 17:58:45

Pprofile

line_profiler (już zaprezentowane tutaj) również zainspirowały pprofile, który jest opisany jako:

Linia-ziarnistość, wątek-świadomy deterministyczny i statystyczny czysty-python profiler

Zapewnia ziarnistość linii jako line_profiler, jest czystym Pythonem, może być używany jako samodzielne polecenie lub moduł, a nawet może generować pliki w formacie callgrind, które można łatwo analizować za pomocą [k|q]cachegrind.

Vprof

Istnieje również vprof , pakiet Pythona opisany jako:

[...] zapewnienie bogatych i interaktywnych wizualizacji dla różnych charakterystyk programów Pythona, takich jak czas pracy i zużycie pamięci.

heatmap

 35
Author: BenC,
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-05-22 22:48:18

Ładnym modułem profilowania jest line_profiler (wywoływany za pomocą skryptu kernprof.py). można go pobrać tutaj.

Rozumiem, że cProfile podaje tylko informacje o całkowitym czasie spędzonym w każdej funkcji. Więc poszczególne linie kodu nie są czasowe. Jest to problem w informatyce naukowej, ponieważ często jedna linia może zająć dużo czasu. Również, jak pamiętam, cProfile nie złapał czasu spędzonego w say numpy.dot.

 33
Author: Ian Langmore,
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-10-20 16:05:34

Jest wiele świetnych odpowiedzi, ale albo używają linii poleceń, albo jakiegoś zewnętrznego programu do profilowania i / lub sortowania wyników.

Naprawdę przegapiłem jakiś sposób, który mógłbym wykorzystać w moim IDE (eclipse-PyDev) bez dotykania linii poleceń lub instalowania czegokolwiek. Oto i ona.

Profilowanie bez wiersza poleceń

def count():
    from math import sqrt
    for x in range(10**5):
        sqrt(x)

if __name__ == '__main__':
    import cProfile, pstats
    cProfile.run("count()", "{}.profile".format(__file__))
    s = pstats.Stats("{}.profile".format(__file__))
    s.strip_dirs()
    s.sort_stats("time").print_stats(10)

Zobacz docs lub inne odpowiedzi, aby uzyskać więcej informacji.

 16
Author: David Mašek,
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
2020-06-20 09:12:55

Po odpowiedzi Joe Shawa na temat wielowątkowego kodu, który nie działa zgodnie z oczekiwaniami, pomyślałem, że metoda runcall w cProfile wykonuje jedynie self.enable() i self.disable() wywołania wokół funkcji profilowanej, więc możesz po prostu zrobić to sam i mieć dowolny kod pomiędzy, przy minimalnej ingerencji w istniejący kod.

 12
Author: PypeBros,
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-11-09 12:59:04

Tylko terminal (i najprostsze) rozwiązanie, w przypadku, gdy wszystkie te fancy UI nie instalują się lub nie uruchamiają:
ignoruj cProfile CAŁKOWICIE i zastąp ją pyinstrument, która będzie zbierać i wyświetlać drzewo wywołań zaraz po wykonaniu.

Zainstaluj:

$ pip install pyinstrument

Profil i wynik wyświetlania:

$ python -m pyinstrument ./prog.py
Działa z python2 i 3.

[edytuj] Dokumentacja API, do profilowania tylko części kodu, znajduje się tutaj .

 11
Author: Francois,
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
2020-04-27 11:53:34

W źródle Istnieje bardzo przydatna klasa i dekorator, które mogą bardzo ułatwić profilowanie (nawet dla określonych metod/funkcji). Wyjście można następnie bardzo wygodnie przeglądać w KCacheGrind.

 10
Author: Walter,
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
2017-10-30 17:28:12

CProfile jest świetny do szybkiego profilowania, ale większość czasu kończyło się dla mnie błędami. Funkcja runctx rozwiązuje ten problem, inicjując poprawnie środowisko i zmienne, mam nadzieję, że może się komuś przydać:

import cProfile
cProfile.runctx('foo()', None, locals())
 9
Author: Datageek,
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-03-30 11:11:13

Jeśli chcesz zrobić Profiler zbiorczy, znaczenie uruchomienia funkcji kilka razy z rzędu i obserwowania sumy wyników.

Możesz użyć tego cumulative_profiler dekoratora:

Jest specyficzny dla Pythona >= 3.6, ale możesz usunąć nonlocal, ponieważ działa na starszych wersjach.

import cProfile, pstats

class _ProfileFunc:
    def __init__(self, func, sort_stats_by):
        self.func =  func
        self.profile_runs = []
        self.sort_stats_by = sort_stats_by

    def __call__(self, *args, **kwargs):
        pr = cProfile.Profile()
        pr.enable()  # this is the profiling section
        retval = self.func(*args, **kwargs)
        pr.disable()

        self.profile_runs.append(pr)
        ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
        return retval, ps

def cumulative_profiler(amount_of_times, sort_stats_by='time'):
    def real_decorator(function):
        def wrapper(*args, **kwargs):
            nonlocal function, amount_of_times, sort_stats_by  # for python 2.x remove this row

            profiled_func = _ProfileFunc(function, sort_stats_by)
            for i in range(amount_of_times):
                retval, ps = profiled_func(*args, **kwargs)
            ps.print_stats()
            return retval  # returns the results of the function
        return wrapper

    if callable(amount_of_times):  # incase you don't want to specify the amount of times
        func = amount_of_times  # amount_of_times is the function in here
        amount_of_times = 5  # the default amount
        return real_decorator(func)
    return real_decorator

Przykład

Profilowanie funkcji baz

import time

@cumulative_profiler
def baz():
    time.sleep(1)
    time.sleep(2)
    return 1

baz()

baz biegł 5 razy i wydrukował to:

         20 function calls in 15.003 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10   15.003    1.500   15.003    1.500 {built-in method time.sleep}
        5    0.000    0.000   15.003    3.001 <ipython-input-9-c89afe010372>:3(baz)
        5    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

Określanie ilości razy

@cumulative_profiler(3)
def baz():
    ...
 8
Author: moshevi,
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
2019-09-17 06:37:56

Moim sposobem jest użycie yappi ( https://github.com/sumerc/yappi ). jest to szczególnie przydatne w połączeniu z serwerem RPC, gdzie (nawet tylko do debugowania) rejestruje się metodę uruchamiania, zatrzymywania i drukowania informacji o profilowaniu, np. w ten sposób:

@staticmethod
def startProfiler():
    yappi.start()

@staticmethod
def stopProfiler():
    yappi.stop()

@staticmethod
def printProfiler():
    stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
    statPrint = '\n'
    namesArr = [len(str(stat[0])) for stat in stats.func_stats]
    log.debug("namesArr %s", str(namesArr))
    maxNameLen = max(namesArr)
    log.debug("maxNameLen: %s", maxNameLen)

    for stat in stats.func_stats:
        nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
        log.debug('nameAppendSpaces: %s', nameAppendSpaces)
        blankSpace = ''
        for space in nameAppendSpaces:
            blankSpace += space

        log.debug("adding spaces: %s", len(nameAppendSpaces))
        statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + "\t" + str(
            round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"

    log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
    log.log(1000, statPrint)

Następnie podczas pracy programu możesz uruchomić profiler w dowolnym momencie, wywołując metodę startProfiler RPC i zrzucić informacje o profilowaniu do pliku dziennika, wywołując printProfiler (lub zmodyfikować metodę rpc, aby zwrócić ją do wywołującego) i uzyskać takie wyjście:

2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
name                                                                                                                                      ncall     ttot    tsub
2014-02-19 16:32:24,128-|SVR-MAIN  |-(Thread-3   )-Level 1000: 
C:\Python27\lib\sched.py.run:80                                                                                                           22        0.11    0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515                                                    22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66                                       1         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464                                                                                    1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243     4         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537                                                                          1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4         0.0     0.0
<string>.__new__:8                                                                                                                        220       0.0     0.0
C:\Python27\lib\socket.py.close:276                                                                                                       4         0.0     0.0
C:\Python27\lib\threading.py.__init__:558                                                                                                 1         0.0     0.0
<string>.__new__:8                                                                                                                        4         0.0     0.0
C:\Python27\lib\threading.py.notify:372                                                                                                   1         0.0     0.0
C:\Python27\lib\rfc822.py.getheader:285                                                                                                   4         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301                                                                                  1         0.0     0.0
C:\Python27\lib\xmlrpclib.py.end:816                                                                                                      3         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467                                                                                         1         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460                                                                               1         0.0     0.0
C:\Python27\lib\SocketServer.py.close_request:475                                                                                         1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066               4         0.0     0.0 

Może nie być zbyt przydatne dla krótkich skryptów, ale pomaga zoptymalizować procesy typu serwera, szczególnie biorąc pod uwagę, że metoda printProfiler może być wywoływana wiele razy w czasie, aby profilować i porównywać np. różne scenariusze użycia programu.

W nowszych wersjach yappi będzie działał następujący kod:

@staticmethod
def printProfile():
    yappi.get_func_stats().print_all()
 6
Author: Mr. Girgitt,
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
2020-01-29 00:55:34

Aby uzyskać szybkie statystyki profilu na notebooku IPython. Można umieścić line_profiler i memory_profiler prosto do ich notebooków.

Innym przydatnym pakietem jest Pympler. Jest to potężny pakiet profilowania, który jest w stanie śledzić klasy, obiekty, funkcje, wycieki pamięci itp. Przykłady poniżej, załączone dokumenty.

Get it!

!pip install line_profiler
!pip install memory_profiler
!pip install pympler

Załaduj to!

%load_ext line_profiler
%load_ext memory_profiler

Użycie to!


%czas

%time print('Outputs CPU time,Wall Clock time') 
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs

Daje:

  • CPU times: CPU Level execution time
  • sys times: czas wykonania na poziomie systemu
  • razem: czas PROCESORA + czas systemowy
  • Wall time: Zegar Ścienny czas

%timeit

%timeit -r 7 -n 1000 print('Outputs execution time of the snippet') 
#1000 loops, best of 7: 7.46 ns per loop
  • daje najlepszy czas z podanej liczby biegów (r) W pętli (N) razy.
  • wyświetla szczegóły dotyczące buforowania systemu:
    • gdy fragmenty kodu są wykonywane wiele razy, system buforuje kilka opearations i nie wykonuje ich ponownie, co może utrudnić dokładność raportów profilowych.

%prun

%prun -s cumulative 'Code to profile' 

Daje:

  • liczba wywołań funkcji (ncalls)
  • has entries per function call (distinct)
  • Czas na połączenie (percall)
  • upłynął czas do wywołania funkcji (cumtime)
  • nazwa func / modułu o nazwie itd...

Profil zbiorczy


% memit

%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB

Daje:

  • wykorzystanie pamięci

%lprun

#Example function
def fun():
  for i in range(10):
    print(i)

#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()

Daje:

  • statystyki linii

LineProfile


Sys.getsizeof

sys.getsizeof('code to profile')
# 64 bytes

Zwraca rozmiar obiektu w bajtach.


Asizeof () from pympler

from pympler import asizeof
obj = [1,2,("hey","ha"),3]
print(asizeof.asizeof(obj,stats=4))

Pympler.asizeof może być używany do badania ilości pamięci niektórych obiektów Pythona konsumować. W przeciwieństwie do sys.getsizeof, asizeof rozmiar obiektów rekurencyjnie

pympler.asizeof


Tracker od pymplera

from pympler import tracker
tr = tracker.SummaryTracker()
def fun():
  li = [1,2,3]
  di = {"ha":"haha","duh":"Umm"}
fun()
tr.print_diff()

Śledzi czas życia funkcji.

wyjście trackera

Pakiet Pympler składa się z ogromnej liczby wysokiej funkcji użytkowych do profilowania kodu. Tego wszystkiego nie można tutaj ująć. Zapoznaj się z załączoną dokumentacją implementacji verbose profile.

Pympler doc

 5
Author: Aditya Patnaik,
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
2020-06-20 09:12:55

Gprof2dot_magic

Magiczna funkcja dla gprof2dot do profilowania dowolnej instrukcji Pythona jako wykresu punktowego w JupyterLab lub Jupyter Notebook.

Tutaj wpisz opis obrazka

GitHub repo: https://github.com/mattijn/gprof2dot_magic

Instalacja

Upewnij się, że masz pakiet Pythona gprof2dot_magic.

pip install gprof2dot_magic

Jego zależności gprof2dot i graphviz zostaną również zainstalowane

Użycie

Aby włączyć magię funkcja, najpierw załaduj moduł gprof2dot_magic

%load_ext gprof2dot_magic

A następnie profiluje dowolną instrukcję liniową jako wykres punktowy jako taki:

%gprof2dot print('hello world')

Tutaj wpisz opis obrazka

 4
Author: Mattijn,
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
2019-07-19 14:25:49

Chcesz wiedzieć, co ten skrypt w Pythonie robi? Wpisz Sprawdź Shell. Inspect Shell pozwala drukować / zmieniać globale i uruchamiać działa bez przerywania uruchomionego skryptu. Teraz z autouzupełnianie i historia poleceń (tylko w Linuksie).

Inspect Shell nie jest debuggerem w stylu pdb.

Https://github.com/amoffat/Inspect-Shell

Przydałoby Ci się to (i twój zegarek).
 3
Author: Colonel Panic,
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-22 14:52:15

Aby dodać do https://stackoverflow.com/a/582337/1070617 ,

Napisałem ten moduł, który pozwala używać cProfile i łatwo przeglądać jego wyjście. Więcej tutaj: https://github.com/ymichael/cprofilev

$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.

Zobacz też: http://ymichael.com/2014/03/08/profiling-python-with-cprofile.html o tym, jak rozumieć zebrane statystyki.

 3
Author: michael,
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
2017-05-23 11:33:32

Nowym narzędziem do obsługi profilowania w Pythonie jest PyVmMonitor: http://www.pyvmmonitor.com/

Posiada kilka unikalnych cech, takich jak

    W przeciwieństwie do innych programów, nie można ich używać.]}
  • profilowanie na żądanie z integracją Yappi
  • profil na innej maszynie
  • Obsługa wielu procesów( multiprocessing, django...)
  • próbkowanie na żywo / widok PROCESORA (z wyborem zakresu czasu)
  • deterministyczne profilowanie za pomocą cProfile/profile integracja
  • analiza istniejących wyników PStats
  • otwórz pliki DOT
  • Programatic API access
  • Grupuj próbki według metody lub linii
  • PyDev integration
  • Integracja PyCharm

Uwaga: jest komercyjny, ale darmowy dla open source.

 3
Author: Fabio Zadrozny,
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-04-28 22:50:08

To zależy od tego, co chcesz zobaczyć z profilowania. Simple time metryki mogą być podane przez (bash).

time python python_prog.py

Nawet '/ usr / bin / time 'może wyświetlić szczegółowe metryki używając flagi '-- verbose'.

Aby sprawdzić metryki czasu podane przez każdą z funkcji i lepiej zrozumieć, ile czasu poświęca się na funkcje, możesz użyć wbudowanego cProfile w Pythonie.

Przechodząc do bardziej szczegółowych metryk, takich jak wydajność, czas nie jest jedyną metryką. Możesz martwić się o pamięć, wątki itd.
Opcje profilowania:
1. line_profiler jest innym profilerem używanym powszechnie do wyszukiwania metryk czasu linia po linii.
2. memory_profiler jest narzędziem do profilowania wykorzystania pamięci.
3. heopy (z projektu Guppy) Profil jak obiekty w stercie są używane.

Są to niektóre z tych, których zwykle używam. Ale jeśli chcesz dowiedzieć się więcej, spróbuj przeczytać tę książkę Jest to całkiem dobra książka o rozpoczynaniu z myślą o wydajności. Ty może przejść do zaawansowanych tematów dotyczących korzystania z Cythona i JIT(Just-In-time) skompilowanego Pythona.

 3
Author: VishalMishra,
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
2017-11-07 15:42:49

Z profilerem statystycznym, takim jak austin , nie jest wymagane oprzyrządowanie, co oznacza, że można uzyskać dane profilowania z aplikacji Pythona po prostu za pomocą

austin python3 my_script.py

Surowe wyjście nie jest zbyt użyteczne, ale możesz to przełączyć na flamegraph.pl aby uzyskać graficzną reprezentację tych danych, która daje podział na czas (mierzony w mikrosekundach czasu rzeczywistego) jest spędzany.

austin python3 my_script.py | flamegraph.pl > my_script_profile.svg
 2
Author: Phoenix87,
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
2020-03-13 10:10:12

Jest też Profiler statystyczny o nazwie statprof. Jest to Profiler próbkowania, więc dodaje minimalny narzut do kodu i daje timingi liniowe (nie tylko oparte na funkcjach). Jest bardziej odpowiedni do miękkich aplikacji w czasie rzeczywistym, takich jak gry, ale może być mniej precyzyjny niż cProfile.

Wersja w pypi jest trochę stara, więc można ją zainstalować za pomocą {[3] } poprzez podanie repozytorium git:

pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01

Możesz go uruchomić tak:

import statprof

with statprof.profile():
    my_questionable_function()

Zobacz https://stackoverflow.com/a/10333592/320036

 1
Author: z0r,
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
2017-05-23 11:47:36

Właśnie stworzyłem swój własny profiler inspirowany pypref_time:

Https://github.com/modaresimr/auto_profiler

Dodając dekorator wyświetli drzewo czasochłonnych funkcji

@Profiler(depth=4, on_disable=show)

Install by: pip install auto_profiler

Przykład

import time # line number 1
import random

from auto_profiler import Profiler, Tree

def f1():
    mysleep(.6+random.random())

def mysleep(t):
    time.sleep(t)

def fact(i):
    f1()
    if(i==1):
        return 1
    return i*fact(i-1)


def show(p):
    print('Time   [Hits * PerHit] Function name [Called from] [Function Location]\n'+\
          '-----------------------------------------------------------------------')
    print(Tree(p.root, threshold=0.5))
    
@Profiler(depth=4, on_disable=show)
def main():
    for i in range(5):
        f1()

    fact(3)


if __name__ == '__main__':
    main()

Przykładowe Wyjście


Time   [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974]  main  [auto-profiler/profiler.py:267]  [/test/t2.py:30]
├── 5.954s [5 * 1.191]  f1  [/test/t2.py:34]  [/test/t2.py:14]
│   └── 5.954s [5 * 1.191]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
│       └── 5.954s [5 * 1.191]  <time.sleep>
|
|
|   # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020]  fact  [/test/t2.py:36]  [/test/t2.py:20]
    ├── 0.849s [1 * 0.849]  f1  [/test/t2.py:21]  [/test/t2.py:14]
    │   └── 0.849s [1 * 0.849]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
    │       └── 0.849s [1 * 0.849]  <time.sleep>
    └── 2.171s [1 * 2.171]  fact  [/test/t2.py:24]  [/test/t2.py:20]
        ├── 1.552s [1 * 1.552]  f1  [/test/t2.py:21]  [/test/t2.py:14]
        │   └── 1.552s [1 * 1.552]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]
        └── 0.619s [1 * 0.619]  fact  [/test/t2.py:24]  [/test/t2.py:20]
            └── 0.619s [1 * 0.619]  f1  [/test/t2.py:21]  [/test/t2.py:14]
 1
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
2020-06-20 09:12:55

Gdy nie jestem rootem na serwerze, używam lsprofcalltree.py i uruchom mój program tak:

python lsprofcalltree.py -o callgrind.1 test.py

Następnie mogę otworzyć raport za pomocą dowolnego oprogramowania kompatybilnego z callgrind, takiego jak qcachegrind

 0
Author: Vincent Fenet,
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
2017-02-02 10:18:41