Suche…


Bemerkungen

Wenn Sie versuchen, die Leistung eines Python-Skripts zu verbessern, sollten Sie in erster Linie den Engpass Ihres Skripts ermitteln und beachten, dass keine Optimierung eine schlechte Wahl der Datenstrukturen oder einen Fehler in Ihrem Algorithmusdesign ausgleichen kann. Sie können Leistungsengpässe identifizieren, indem Sie Ihr Skript profilieren . Zweitens sollten Sie nicht zu früh im Codierprozess auf Kosten der Lesbarkeit / des Designs / der Qualität optimieren. Donald Knuth äußerte sich zur Optimierung wie folgt:

„Wir sollten kleine Wirkungsgrade vergessen, etwa 97% der Zeit: vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen in den kritischen 3% nicht aufgeben. “

Code-Profiling

In erster Linie sollten Sie in der Lage sein, den Engpass Ihres Skripts zu finden und zu beachten, dass keine Optimierung eine schlechte Wahl der Datenstruktur oder einen Fehler in Ihrem Algorithmusdesign ausgleichen kann. Zweitens sollten Sie nicht zu früh im Codierprozess auf Kosten der Lesbarkeit / des Designs / der Qualität optimieren. Donald Knuth äußerte sich zur Optimierung wie folgt:

"Wir sollten kleine Wirkungsgrade vergessen, etwa 97% der Zeit: vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen in diesen kritischen 3% nicht aufgeben."

Um Ihren Code zu profilieren, stehen Ihnen mehrere Werkzeuge zur Verfügung: cProfile (oder das langsamere profile ) aus der Standardbibliothek, line_profiler und timeit . Jeder von ihnen dient einem anderen Zweck.

cProfile ist ein deterministischer Profiler: Funktionsaufruf, Funktionsrückkehr und Ausnahmeereignisse werden überwacht, und für die Intervalle zwischen diesen Ereignissen (bis zu 0,001 Sekunden) werden genaue Zeitpunkte festgelegt. Die Bibliotheksdokumentation ([ https://docs.python.org/2/library/profile.html __1]) liefert einen einfachen Anwendungsfall

import cProfile
def f(x):
    return "42!"
cProfile.run('f(12)')

Oder wenn Sie es vorziehen, Teile Ihres vorhandenen Codes einzuwickeln:

import cProfile, pstats, StringIO
pr = cProfile.Profile()
pr.enable()
# ... do something ...
# ... long ...
pr.disable()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print s.getvalue()

Dadurch werden Ausgaben wie in der folgenden Tabelle erstellt, in denen Sie schnell sehen können, wo Ihr Programm die meiste Zeit verbringt, und die zu optimierenden Funktionen identifizieren.

         3 function calls in 0.000 seconds

Ordered by: standard name
ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.000    0.000    0.000    0.000 <stdin>:1(f)
     1    0.000    0.000    0.000    0.000 <string>:1(<module>)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

Das Modul line_profiler ([ https://github.com/rkern/line_profiler([1]) ist hilfreich, um eine zeilenweise Analyse des Codes zu erhalten. Dies ist offensichtlich nicht für lange Skripte zu beherrschen, sondern richtet sich an Snippets. Weitere Informationen finden Sie in der Dokumentation. Der einfachste Weg, um loszulegen, ist die Verwendung des Kernprof-Skripts, wie auf der Paketseite erläutert. Beachten Sie, dass Sie die Funktion (en) für das Profil manuell festlegen müssen.

$ kernprof -l script_to_profile.py

kernprof erstellt eine Instanz von LineProfiler und fügt sie mit dem __builtins__ in den __builtins__ Namespace ein. Es wurde geschrieben, um als Dekorateur verwendet zu werden, so dass Sie in Ihrem Skript die Funktionen dekorieren, die Sie mit @profile profilieren @profile .

@profile
def slow_function(a, b, c):
    ...

Das Standardverhalten von Kernprof besteht darin, die Ergebnisse in eine Binärdatei script_to_profile.py.lprof . Sie können kernprof anweisen, die formatierten Ergebnisse sofort mit der Option [-v / - view] am Terminal anzuzeigen. Ansonsten können Sie die Ergebnisse später wie folgt anzeigen:

$ python -m line_profiler script_to_profile.py.lprof

Schließlich bietet timeit eine einfache Möglichkeit zum Testen eines timeit oder eines kleinen Ausdrucks sowohl über die Befehlszeile als auch über die Python-Shell. Dieses Modul beantwortet Fragen, z. B. ist es schneller, ein Listenverständnis auszuführen oder die integrierte list() wenn Sie einen Satz in eine Liste umwandeln. Suchen Sie nach dem setup Schlüsselwort oder der Option -s , um den Setup-Code hinzuzufügen.

>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.8187260627746582

von einem Terminal

$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow