Ich fand die verschiedenen Antworten sehr elegant (insbesondere die von Alex Martelli), wollte aber die Leistung aus erster Hand quantifizieren und habe mir das folgende Skript ausgedacht:
from itertools import repeat
N = 10000000
def payload(a):
pass
def standard(N):
for x in range(N):
payload(None)
def underscore(N):
for _ in range(N):
payload(None)
def loopiter(N):
for _ in repeat(None, N):
payload(None)
def loopiter2(N):
for _ in map(payload, repeat(None, N)):
pass
if __name__ == '__main__':
import timeit
print("standard: ",timeit.timeit("standard({})".format(N),
setup="from __main__ import standard", number=1))
print("underscore: ",timeit.timeit("underscore({})".format(N),
setup="from __main__ import underscore", number=1))
print("loopiter: ",timeit.timeit("loopiter({})".format(N),
setup="from __main__ import loopiter", number=1))
print("loopiter2: ",timeit.timeit("loopiter2({})".format(N),
setup="from __main__ import loopiter2", number=1))
Ich habe mir auch eine alternative Lösung ausgedacht, die auf der von Martelli aufbaut und map()
zum Aufrufen der Nutzlastfunktion verwendet wird. OK, ich habe ein bisschen geschummelt, weil ich mir die Freiheit genommen habe, die Nutzlast dazu zu bringen, einen Parameter zu akzeptieren, der verworfen wird: Ich weiß nicht, ob es einen Weg gibt, dies zu umgehen. Trotzdem hier die Ergebnisse:
standard: 0.8398549720004667
underscore: 0.8413165839992871
loopiter: 0.7110594899968419
loopiter2: 0.5891903560004721
Die Verwendung der Karte ergibt also eine Verbesserung von ungefähr 30% gegenüber dem Standard für Schleifen und zusätzlichen 19% gegenüber Martellis.