Funktionen benchmarken mit timeout.
Verfasst: Montag 10. Februar 2014, 11:45
Hi all,
kennt ihr das allgemeine Problem, ihr habt 3-4 Ideen, wie ihr eine Funktion implementieren könntet.
Die eine ist pythonisch und sieht schön kurz und elegant aus, die andere sieht mehr nach C aus und hässlich,
dann kommen noch verschiedene Variationen hinzu, die einen mehr oder weniger verständlich, die anderen mehr oder weniger optimiert.
Am Ende stellt sich aber die Frage, welche ist schneller?
Normalerweise benchmarke ich meine Funktionen selber, a la ...
Das ist mega-käsig, ich weiss. Zudem bin ich gerade eben durch suchen nach "timeout" im Forum auf das "timeit" Modul gestoßen, welches mein Vorgehen oben komplett ersetzt.
Aber deswegen bin ich nicht hier, denn ich suche nach eine ganz anderen Lösung:
Also ein allgemeines Problem beim Code ist ja, dass man kein echtes Gefühl hat für die absolute Ausführungsgeschwindigkeit.
D.h. selbst wenn man sich zum benchmarken für die Methodik "wieviele Sekunden brauchst du für x Durchgänge" entscheidet,
muss man trotzdem zuvor erstmal ein paar Durchgänge ausprobieren, um überhaupt ein Gefühl dafür zu bekommen, wie man
die Anzahl der Iterationen x wählt für jede einzelne Funktion, denn manche brauchen Millisekunden, manche Minuten, andere fast ne Stunde.
Aus diesem Grund möchte ich es eigentlich umgekehrt haben: "wieviele Iterationen hast du für eine fixe Zeit x geschafft."
Dazu bräuchte ich eine Möglichkeit, eine Funktion auszuführen, jeden vollständigen Durchlauf zu zählen (counter) und wenn das definierte Timeout,
zum Beispiel 10 Sekunden, erreicht ist, soll die (äussere) Benchmarkfunktionen sofort abbrechen und die ge-benchmarkte Funktionen killen.
Fantasiecode:
Und ja, bitte nicht auf eventlet verweisen, das hab ich schon durch googlen zufällig entdeckt, aber ich würde gerne wissen, wie man das mit Python-boardmitteln am besten macht.
Solange ich keine gescheite Lösung habe nutze ich ne total jämmerliche Fallbacklösung, die keine Garantie dafür gibt, tatsächlich nach dem timeout abzubrechen.
Wenn func() hier mehr als eine Stunde dauert, läuft genau ein func() komplett durch, und nach einer Stunde erst hört benchme auf und gibt als counter 1 zurück. Toll.
Also ich hoffe ich habe das Problem klar genug dargestellt und bin froh um Vorschläge, wie man das am besten mit Python-Boardmitteln implementieren könnte.
Im Voraus vielen Dank für Eure Antworten und Beiträge.
kennt ihr das allgemeine Problem, ihr habt 3-4 Ideen, wie ihr eine Funktion implementieren könntet.
Die eine ist pythonisch und sieht schön kurz und elegant aus, die andere sieht mehr nach C aus und hässlich,
dann kommen noch verschiedene Variationen hinzu, die einen mehr oder weniger verständlich, die anderen mehr oder weniger optimiert.
Am Ende stellt sich aber die Frage, welche ist schneller?
Normalerweise benchmarke ich meine Funktionen selber, a la ...
Code: Alles auswählen
import time
def func_v1():
do something ...
def func_v2():
do something, slightly different ...
iterations=10000
v1_start = time.time()
for _ in xrange(iterations):
func_v1()
print "func_v1() took {0:f} seconds for {1:d} iterations.".format(time.time() - v1_start, iterations)
v2_start = time.time()
for _ in xrange(iterations):
func_v2()
print "func_v2() took {0:f} seconds for {1:d} iterations.".format(time.time() - v2_start, iterations)Aber deswegen bin ich nicht hier, denn ich suche nach eine ganz anderen Lösung:
Also ein allgemeines Problem beim Code ist ja, dass man kein echtes Gefühl hat für die absolute Ausführungsgeschwindigkeit.
D.h. selbst wenn man sich zum benchmarken für die Methodik "wieviele Sekunden brauchst du für x Durchgänge" entscheidet,
muss man trotzdem zuvor erstmal ein paar Durchgänge ausprobieren, um überhaupt ein Gefühl dafür zu bekommen, wie man
die Anzahl der Iterationen x wählt für jede einzelne Funktion, denn manche brauchen Millisekunden, manche Minuten, andere fast ne Stunde.
Aus diesem Grund möchte ich es eigentlich umgekehrt haben: "wieviele Iterationen hast du für eine fixe Zeit x geschafft."
Dazu bräuchte ich eine Möglichkeit, eine Funktion auszuführen, jeden vollständigen Durchlauf zu zählen (counter) und wenn das definierte Timeout,
zum Beispiel 10 Sekunden, erreicht ist, soll die (äussere) Benchmarkfunktionen sofort abbrechen und die ge-benchmarkte Funktionen killen.
Fantasiecode:
Code: Alles auswählen
def benchthis(func, timeout):
count = 0
t = Timeout.set_timeout(timeout)
try:
func()
count += 1
except t.timeout_reached(), e:
pass
print "completet {0:d} iterations in {1:f} seconds.".format(count, timeout)Solange ich keine gescheite Lösung habe nutze ich ne total jämmerliche Fallbacklösung, die keine Garantie dafür gibt, tatsächlich nach dem timeout abzubrechen.
Code: Alles auswählen
def benchme(func, timeout):
c = 0
start = time.time()
while timeout < (time.time() - start):
func()
c += 1
return c, timeoutAlso ich hoffe ich habe das Problem klar genug dargestellt und bin froh um Vorschläge, wie man das am besten mit Python-Boardmitteln implementieren könnte.
Im Voraus vielen Dank für Eure Antworten und Beiträge.