Ich kämpfe mit Timeit damit und habe mich gefragt, ob jemand irgendwelche Tipps hat
Grundsätzlich habe ich eine Funktion (an die ich einen Wert übergebe), deren Geschwindigkeit ich testen und erstellen möchte:
if __name__=='__main__':
from timeit import Timer
t = Timer(superMegaIntenseFunction(10))
print t.timeit(number=1)
aber wenn ich es starte, bekomme ich seltsame Fehler wie vom timeit-Modul:
ValueError: stmt is neither a string nor callable
Wenn ich die Funktion alleine ausführe, funktioniert sie einwandfrei. Wenn ich es in das Time-It-Modul einbinde, erhalte ich die Fehler (ich habe versucht, doppelte Anführungszeichen und ohne ... gleiche Ausgabe zu verwenden).
Vorschläge wären super!
Vielen Dank!
python
debugging
benchmarking
Verlorene Seele
quelle
quelle
timeit 5*5
beträgt 33 ns undtimeit (lambda: 5*5)()
233 ns.timeit
mit dem Lambda (das Skript ist eingefroren; die Methode, mit der ich die Ausführungszeit gemessen habe, ist dasretrbinary
Herunterladen über FTP mit demftplib
). Sobald ich dasTimer
Objekt benutzte , wirkte es plötzlich wie ein Zauber. Keine Ahnung, was passiert ist ...: DTimer(superMegaIntenseFunction(10))
bedeutet "anrufensuperMegaIntenseFunction(10)
, dann das Ergebnis an übergebenTimer
". Das ist eindeutig nicht das, was du willst.Timer
erwartet entweder einen aufrufbaren (so wie es sich anhört: etwas, das aufgerufen werden kann, wie eine Funktion) oder einen String (damit der Inhalt des Strings als Python-Code interpretiert werden kann).Timer
funktioniert, indem Sie das aufrufbare Ding wiederholt aufrufen und sehen, wie viel Zeit benötigt wird.Timer(superMegaIntenseFunction)
würde die Typprüfung bestehen, dasuperMegaIntenseFunction
aufrufbar ist. IchTimer
würde jedoch nicht wissen, an welche Werte übergeben werden sollsuperMegaIntenseFunction
.Der einfache Weg, dies zu umgehen, besteht natürlich darin, eine Zeichenfolge mit dem Code zu verwenden. Wir müssen ein 'Setup'-Argument an den Code übergeben, da die Zeichenfolge in einem neuen Kontext "als Code interpretiert" wird - sie hat keinen Zugriff darauf
globals
, sodass Sie ein weiteres Stück Code ausführen müssen, um die Definition zu erstellen verfügbar - siehe Antwort von @ oxtopus.Mit
lambda
(wie in der Antwort von @ Pablo) können wir den Parameter10
an einen Aufruf von bindensuperMegaIntenseFunction
. Alles , was wir tun , eine andere Funktion schafft, die keine Argumente übernimmt, und fordertsuperMegaIntenseFunction
mit10
. Es ist so, als hätten Siedef
eine andere Funktion wie diese erstellt, nur dass die neue Funktion keinen Namen erhält (weil sie keinen benötigt).quelle
Sie sollten eine Zeichenfolge übergeben. dh
t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')
quelle
Ein Hinweis für zukünftige Besucher. Wenn Sie dafür sorgen müssen, dass es im
pdb
Debugger funktioniert undsuperMegaIntenseFunction
nicht im globalen Bereich liegt, können Sie es zum Laufen bringen, indem Sie Folgendes hinzufügenglobals
:globals()['superMegaIntenseFunction'] = superMegaIntenseFunction timeit.timeit(lambda: superMegaIntenseFunction(x))
quelle
Eine Möglichkeit wäre die Verwendung von Partial, sodass die Funktion 'superMegaIntenseFunction' als aufrufbare Funktion (dh ohne ()) im Timer oder direkt in timeit.timeit verwendet wird. Bei Verwendung von Partial wird das Argument an die Funktion übergeben, wenn es vom Timer aufgerufen wird.
from functools import partial from timeit import timeit print(timeit(partial(superMegaIntenseFunction, 10), number=1))
quelle