1730 Stimmen

Wie kann ich ein Python-Skript profilieren?

Projekt Euler und andere Programmierwettbewerbe haben oft eine maximale Laufzeit oder die Teilnehmer rühmen sich damit, wie schnell ihre spezielle Lösung läuft. Bei Python sind die Ansätze manchmal etwas plump - z. B. das Hinzufügen von Zeitmessungscode zu __main__ .

Wie kann man ein Profil erstellen, wie lange ein Python-Programm zur Ausführung benötigt?

1791voto

Chris Lawlor Punkte 43983

Python enthält einen Profiler namens cProfil . Es gibt nicht nur die Gesamtlaufzeit an, sondern auch die Zeiten für jede Funktion einzeln und sagt Ihnen, wie oft jede Funktion aufgerufen wurde, so dass Sie leicht feststellen können, wo Sie Optimierungen vornehmen sollten.

Sie können es von Ihrem Code aus oder vom Interpreter aus aufrufen, etwa so:

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

Noch nützlicher ist, dass Sie das cProfile bei der Ausführung eines Skripts aufrufen können:

python -m cProfile myscript.py

Um es noch einfacher zu machen, habe ich eine kleine Batch-Datei namens 'profile.bat' erstellt:

python -m cProfile %1

Ich muss also nur noch rennen:

profile euler048.py

Und ich verstehe das:

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: Aktualisierter Link zu einer guten Videoquelle von der PyCon 2013 mit dem Titel Python-Profilierung
Auch über YouTube .

531voto

gak Punkte 30810

Vor einiger Zeit habe ich pycallgraph das aus Ihrem Python-Code eine Visualisierung erzeugt. 編集する。 Ich habe das Beispiel aktualisiert, damit es mit 3.3 funktioniert, der neuesten Version zum Zeitpunkt der Erstellung dieses Artikels.

Nach einem pip install pycallgraph und die Installation GraphViz können Sie es über die Befehlszeile ausführen:

pycallgraph graphviz -- ./mypythonscript.py

Oder Sie können ein Profil für bestimmte Teile Ihres Codes erstellen:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

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

In beiden Fällen wird eine pycallgraph.png Datei ähnlich der folgenden Abbildung:

enter image description here

241voto

Joe Shaw Punkte 21088

Es ist erwähnenswert, dass die Verwendung des Profilers nur (standardmäßig) auf dem Hauptthread funktioniert und Sie keine Informationen von anderen Threads erhalten, wenn Sie diese verwenden. Dies kann ein kleines Problem darstellen, da es in der Anleitung nicht erwähnt wird. Profiler-Dokumentation .

Wenn Sie auch Threads profilieren möchten, sollten Sie sich die threading.setprofile() Funktion in den Dokumenten.

Sie können auch Ihre eigene threading.Thread Unterklasse, um dies zu tun:

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,))

und verwenden diese ProfiledThread Klasse anstelle der Standardklasse. Es könnte Ihnen mehr Flexibilität geben, aber ich bin nicht sicher, ob es sich lohnt, vor allem, wenn Sie Code von Drittanbietern verwenden, die Ihre Klasse nicht verwenden würden.

189voto

CodeCabbie Punkte 2506

Einfachste y schnellste um herauszufinden, wohin die ganze Zeit vergeht.

1. pip install snakeviz

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

3. snakeviz temp.dat

Zeichnet ein Tortendiagramm in einem Browser. Der größte Teil ist die Problemfunktion. Sehr einfach.

180voto

brent.payne Punkte 4759

Das Python-Wiki ist eine großartige Seite für Profiling-Ressourcen: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

sowie die Python-Dokumente: http://docs.python.org/library/profile.html

wie von Chris Lawlor gezeigt, ist cProfile ein großartiges Werkzeug und kann leicht zum Drucken auf dem Bildschirm verwendet werden:

python -m cProfile -s time mine.py <args>

oder zu archivieren:

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

PS> Wenn Sie Ubuntu benutzen, stellen Sie sicher, dass Sie python-profile installieren

apt-get install python-profiler 

Wenn Sie in eine Datei ausgeben, können Sie mit den folgenden Tools schöne Visualisierungen erhalten

PyCallGraph : ein Werkzeug zur Erstellung von Aufrufdiagrammen
installieren:

 pip install pycallgraph

laufen:

 pycallgraph mine.py args

Ansicht:

 gimp pycallgraph.png

Sie können die png-Datei mit einem beliebigen Programm anzeigen, ich habe Gimp verwendet.
Leider bekomme ich oft

dot: Graph ist zu groß für cairo-renderer Bitmaps. Skalierung um 0,257079 zur Anpassung

was meine Bilder unbrauchbar klein macht. Deshalb erstelle ich in der Regel svg-Dateien:

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

PS> Stellen Sie sicher, dass Sie Graphviz installieren (das das Dot-Programm bereitstellt):

pip install graphviz

Alternatives Graphing mit gprof2dot via @maxy / @quodlibetor :

pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X