Hier sind meine Ergebnisse, nachdem ich hier viele gute Antworten sowie einige andere Artikel durchgesehen habe.
Erstens, wenn Sie zwischen timeit
und diskutieren time.time
, timeit
hat das zwei Vorteile:
timeit
Wählt den besten verfügbaren Timer für Ihr Betriebssystem und Ihre Python-Version aus.
timeit
Deaktiviert die Speicherbereinigung. Dies ist jedoch nicht das, was Sie möglicherweise möchten oder nicht möchten.
Das Problem ist nun, dass timeit
es nicht so einfach zu bedienen ist, da es eingerichtet werden muss und die Dinge hässlich werden, wenn Sie eine Reihe von Importen haben. Idealerweise möchten Sie nur einen Dekorateur oder verwenden with
Block und messen die Zeit. Leider ist hierfür nichts eingebaut, sodass Sie zwei Möglichkeiten haben:
Option 1: Verwenden Sie die Timebudget-Bibliothek
Das Zeitbudget ist eine vielseitige und sehr einfache Bibliothek, die Sie nach der Pip-Installation nur in einer Codezeile verwenden können.
@timebudget # Record how long this function takes
def my_method():
# my code
Option 2: Verwenden Sie das Codemodul direkt
Ich habe unten ein kleines Utility-Modul erstellt.
# utils.py
from functools import wraps
import gc
import timeit
def MeasureTime(f, no_print=False, disable_gc=False):
@wraps(f)
def _wrapper(*args, **kwargs):
gcold = gc.isenabled()
if disable_gc:
gc.disable()
start_time = timeit.default_timer()
try:
result = f(*args, **kwargs)
finally:
elapsed = timeit.default_timer() - start_time
if disable_gc and gcold:
gc.enable()
if not no_print:
print('"{}": {}s'.format(f.__name__, elapsed))
return result
return _wrapper
class MeasureBlockTime:
def __init__(self,name="(block)", no_print=False, disable_gc=False):
self.name = name
self.no_print = no_print
self.disable_gc = disable_gc
def __enter__(self):
self.gcold = gc.isenabled()
if self.disable_gc:
gc.disable()
self.start_time = timeit.default_timer()
def __exit__(self,ty,val,tb):
self.elapsed = timeit.default_timer() - self.start_time
if self.disable_gc and self.gcold:
gc.enable()
if not self.no_print:
print('Function "{}": {}s'.format(self.name, self.elapsed))
return False #re-raise any exceptions
Jetzt können Sie jede Funktion zeitlich festlegen, indem Sie einen Dekorateur davor stellen:
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
Wenn Sie einen Teil des Codes zeitlich festlegen möchten, fügen Sie ihn einfach in den with
Block ein:
import utils
#somewhere in my code
with utils.MeasureBlockTime("MyBlock"):
#do something time consuming
for i in range(10000):
print(i)
# rest of my code
Vorteile:
Es gibt mehrere Versionen mit halber Rückseite, daher möchte ich auf einige Highlights hinweisen:
- Verwenden Sie aus den zuvor beschriebenen Gründen den Timer von timeit anstelle von time.time.
- Sie können GC während des Timings deaktivieren, wenn Sie möchten.
- Decorator akzeptiert Funktionen mit benannten oder unbenannten Parametern.
- Möglichkeit, das Drucken im Block-Timing zu deaktivieren (verwenden
with utils.MeasureBlockTime() as t
und dann t.elapsed
).
- Möglichkeit, gc für das Block-Timing aktiviert zu halten.