it-swarm.com.de

Wie verwende ich die Python-Zeit, wenn Sie Variablen an Funktionen übergeben?

Ich kämpfe mit Timeit und habe mich gefragt, ob jemand Tipps hatte

Grundsätzlich habe ich eine Funktion (an die ich einen Wert weitergebe), von der ich die Geschwindigkeit testen möchte und diese erstellt habe:

if __name__=='__main__':
    from timeit import Timer
    t = Timer(superMegaIntenseFunction(10))
    print t.timeit(number=1)

aber wenn ich es laufen lasse, bekomme ich seltsame Fehler wie das Timeit-Modul.

ValueError: stmt is neither a string nor callable

Wenn ich die Funktion alleine starte, funktioniert das einwandfrei. Wenn ich es in dem Modul einpacke, bekomme ich die Fehler (ich habe versucht, doppelte Anführungszeichen und ohne..sameoutput zu verwenden).

anregungen wären super!

Vielen Dank!

70
Lostsoul

Machen Sie es aufrufbar:

if __name__=='__main__':
    from timeit import Timer
    t = Timer(lambda: superMegaIntenseFunction(10))
    print(t.timeit(number=1))

Sollte arbeiten

115
Pablo

Timer(superMegaIntenseFunction(10)) bedeutet "rufen Sie superMegaIntenseFunction(10) auf und übergeben Sie das Ergebnis an Timer". Das ist eindeutig nicht das, was Sie wollen. Timer erwartet entweder ein Callable (so wie es aussieht: etwas, das aufgerufen werden kann, wie z. B. eine Funktion) oder einen String (damit der Inhalt des Strings als Python-Code interpretiert werden kann). Timer ruft das aufrufbare Ding wiederholt auf und sieht, wie viel Zeit benötigt wird.

Timer(superMegaIntenseFunction) würde die Typüberprüfung bestehen, da superMegaIntenseFunction aufrufbar ist. Timer würde jedoch nicht wissen, welche Werte an superMegaIntenseFunction übergeben werden sollen.

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 der String in einem neuen Kontext "als Code interpretiert" wird - er hat keinen Zugriff auf die gleiche globals. Daher müssen Sie ein weiteres Bit Code ausführen, um das Definition verfügbar - siehe @ oxtopus Antwort.

Mit lambda (wie in @ Pablos Antwort) können wir den Parameter 10 an einen Aufruf von superMegaIntenseFunction binden. Alles, was wir tun, ist das Erstellen einer anderen Funktion, die keine Argumente akzeptiert und superMegaIntenseFunction mit 10 aufruft. Es ist genau so, als hätten Sie def verwendet, um eine andere Funktion wie diese zu erstellen, nur dass die neue Funktion keinen Namen erhält (weil sie keinen benötigt).

23
Karl Knechtel

Sie sollten eine Zeichenfolge übergeben. d.h.

t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')
18
Austin Marshall

Ein Hinweis für zukünftige Besucher. Wenn Sie es in pdb debugger funktionieren lassen müssen und superMegaIntenseFunction nicht im globalen Bereich ist, können Sie dies durch Hinzufügen zu globals zum Funktionieren bringen:

globals()['superMegaIntenseFunction'] = superMegaIntenseFunction
timeit.timeit(lambda: superMegaIntenseFunction(x))

Beachten Sie, dass der zeitliche Aufwand in diesem Fall aufgrund der zusätzlichen Funktionsaufrufe etwas größer ist. [Quelle]

1

Eine Möglichkeit, dies zu tun, wäre die Verwendung von partial, sodass die Funktion 'superMegaIntenseFunction' als aufrufbar (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))
0
Coding Paradigm