Frage Wie können Sie ein Skript profilieren?


Project Euler und andere Codierungswettbewerbe haben oft eine maximale Zeit zu laufen oder Leute rühmen sich, wie schnell ihre jeweilige Lösung läuft. Mit Python sind die Ansätze manchmal etwas klugdy - d. H. Timing-Code hinzufügen __main__.

Was ist eine gute Möglichkeit, zu profilieren, wie lange ein Python-Programm benötigt?


973
2018-02-24 16:01


Ursprung


Antworten:


Python enthält einen Profiler namens cProfil. Es gibt nicht nur die Gesamtlaufzeit, sondern auch mal jede Funktion einzeln an und teilt Ihnen mit, wie oft jede Funktion aufgerufen wurde, wodurch Sie leicht bestimmen können, wo Sie Optimierungen vornehmen sollten.

Sie können es in Ihrem Code oder vom Interpreter wie folgt aufrufen:

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

Noch sinnvoller können Sie das cProfile aufrufen, wenn Sie ein Skript ausführen:

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

Alles, was ich tun muss, ist:

profile euler048.py

Und ich bekomme 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: Aktualisiert Link zu einer guten Video-Ressource von PyCon 2013 mit dem Titel Python Profilierung
Auch über YouTube.


1073
2018-02-24 16:01



Vor einer Weile habe ich gemacht pycallgraph das generiert eine Visualisierung von Ihrem Python-Code. Bearbeiten: Ich habe das Beispiel aktualisiert, um mit der neuesten Version zu arbeiten.

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

pycallgraph graphviz -- ./mypythonscript.py

Oder Sie können bestimmte Teile Ihres Codes profilieren:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

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

Beide erzeugen ein pycallgraph.png Datei ähnlich der folgenden Abbildung:

enter image description here


349
2017-08-06 05:37



Es lohnt sich, darauf hinzuweisen, dass die Verwendung des Profilers nur (standardmäßig) für den Hauptthread funktioniert und Sie keine Informationen von anderen Threads erhalten, wenn Sie sie verwenden. Dies kann ein bisschen ein Gotcha sein, da es in der Profiler-Dokumentation.

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

Sie könnten auch Ihre eigenen erstellen threading.Thread Unterklasse, um es 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 benutze das ProfiledThread Klasse statt der Standardklasse. Es könnte Ihnen mehr Flexibilität geben, aber ich bin mir nicht sicher, ob es sich lohnt, insbesondere wenn Sie Code von Drittanbietern verwenden, der Ihre Klasse nicht verwenden würde.


167
2017-12-17 16:30



Das Python-Wiki ist eine großartige Seite zum Profilieren von Ressourcen: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code

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

Wie von Chris Lawlor gezeigt, ist cProfile ein großartiges Werkzeug und kann einfach zum Drucken auf den Bildschirm verwendet werden:

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

oder um:

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

PS> Wenn Sie Ubuntu verwenden, stellen Sie sicher, dass Sie Python-Profil installieren

sudo apt-get install python-profiler 

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

PyCallGraph: Ein Werkzeug zum Erstellen von Call-Graph-Bildern
  Installieren:

 sudo pip install pycallgraph

Lauf:

 pycallgraph mine.py args

Aussicht:

 gimp pycallgraph.png

Sie können verwenden, was auch immer Sie möchten, um die PNG-Datei anzuzeigen, habe ich Gimp verwendet
Leider bekomme ich oft

Punkt: Graph ist zu groß für Cairo-Renderer-Bitmaps. Skalierung um 0.257079 passend

was meine Bilder unbrauchbar klein macht. Also ich generiere in der Regel Svg-Dateien:

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

PS> stellen Sie sicher, dass Sie graphviz installieren (welches das Punktprogramm bereitstellt):

sudo pip install graphviz

Alternative Grafik mit gprof2dot über @maxy / @quodlibetor:

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

126
2017-10-08 00:04



@ Maxys Kommentar zu diese Antwort hat mir genug geholfen, dass ich denke, dass es eine eigene Antwort verdient: Ich hatte bereits cProfile-generierte .pstats-Dateien und ich wollte die Dinge nicht mit pycallgraph neu starten, also habe ich es benutzt gprof2dotund bekam hübsche 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

und BLAM!

Es verwendet Punkt (das gleiche, was pycallgraph verwendet), so sieht Ausgabe ähnlich aus. Ich habe den Eindruck, dass gprof2dot weniger Informationen verliert:

gprof2dot example output


113
2017-12-11 23:16



Ich stieß auf ein nützliches Werkzeug namens SchlangenViz bei der Erforschung dieses Themas. SnakeViz ist ein webbasiertes Profilierungs-Visualisierungstool. Es ist sehr einfach zu installieren und zu verwenden. Die übliche Art, wie ich es benutze, besteht darin, eine Statistikdatei mit zu erstellen %prun und dann Analyse in SnakeViz.

Die Hauptvisierte Technik ist Sunburst-Diagramm wie unten gezeigt, in dem die Hierarchie der Funktionsaufrufe als Schichten von Bögen und Zeitinformationen in ihren Winkelbreiten codiert sind.

Das Beste ist, dass Sie mit dem Diagramm interagieren können. Um beispielsweise einen zu vergrößern, kann auf einen Bogen geklickt werden, und der Bogen und seine Nachkommen werden als neuer Sunburst vergrößert, um weitere Details anzuzeigen.

enter image description here


41
2018-05-25 08:06



Erwähnenswert ist auch der GUI cProfile Dump Viewer RunSnakeRun. Sie können damit sortieren und auswählen und damit die relevanten Teile des Programms vergrößern. Die Größe der Rechtecke im Bild ist proportional zur Zeit. Wenn Sie die Maus über ein Rechteck bewegen, wird dieser Anruf in der Tabelle und überall auf der Karte hervorgehoben. Wenn Sie auf ein Rechteck doppelklicken, zoomt es auf diesen Teil. Es zeigt Ihnen, wer diesen Teil anruft und was dieser Teil anruft.

Die beschreibenden Informationen sind sehr hilfreich. Es zeigt Ihnen den Code für dieses Bit, der hilfreich sein kann, wenn Sie mit integrierten Bibliotheksaufrufen arbeiten. Es sagt Ihnen, welche Datei und welche Zeile den Code finden.

Ich möchte auch darauf hinweisen, dass das OP "Profiling" gesagt hat, aber es scheint, er meinte "Timing". Beachten Sie, dass Programme bei der Profilerstellung langsamer ausgeführt werden.

enter image description here


33
2018-02-22 16:18



ich denke, dass cProfile eignet sich hervorragend für Profiling, während kcachegrind ist großartig für die Visualisierung der Ergebnisse. Das pyprof2calltree dazwischen behandelt die Dateikonvertierung.

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree

Um die benötigten Tools zu installieren (zumindest unter Ubuntu):

apt-get install kcachegrind
pip install pyprof2calltree

Das Ergebnis:

Screenshot of the result


29
2018-05-11 08:32



pprofile

line_profiler (bereits hier vorgestellt) auch inspiriert pprofile, die beschrieben wird als:

Liniengranularität, threadsensitives deterministisches und statistisches Python   Profiler

Es bietet Zeilengranularität als line_profiler, ist reines Python, kann als eigenständiger Befehl oder als Modul verwendet werden und kann sogar Dateien im Callgrind-Format generieren, die einfach analysiert werden können [k|q]cachegrind.

vprof

Es gibt auch vprof, ein Python-Paket, beschrieben als:

[...] reichen und interaktiven Visualisierungen für verschiedene Python-Programmmerkmale wie Laufzeit und Speichernutzung.

heatmap


28
2018-03-02 11:36