Diese question und meine answer haben mich über diesen eigenartigen Unterschied zwischen Python 2.7 und Python 3.4 nachdenken lassen. Nehmen Sie den einfachen Beispielcode:Ist das Schneiden in Python 3.4 wirklich langsamer?
import timeit
import dis
c = 1000000
r = range(c)
def slow():
for pos in range(c):
r[pos:pos+3]
dis.dis(slow)
time = timeit.Timer(lambda: slow()).timeit(number=1)
print('%3.3f' % time)
In Python 2.7, ich 0.165~
konsequent erhalten und für Python 3.4 ich konsequent 0.554~
bekommen. Der einzige wesentliche Unterschied zwischen den Disassemblies besteht darin, dass Python 2.7 den Bytecode SLICE+3
ausgibt, während Python 3.4 BUILD_SLICE
gefolgt von BINARY_SUBSCR
ausgibt. Beachten Sie, dass ich die Kandidaten für eine mögliche Verlangsamung von der anderen Frage eliminiert habe, nämlich Strings und die Tatsache, dass xrange
nicht in Python 3.4 existiert (die der Klasse range
von letzterem ähnlich sein soll).
Mit itertools'
islice
ergibt fast identische Timings zwischen den beiden, so dass ich sehr vermuten, dass es das Schneiden ist, das ist die Ursache für den Unterschied hier.
Warum passiert das und gibt es einen Link zu einer autoritativen Quelle, die Verhaltensänderungen dokumentiert?
EDIT: Als Antwort auf die Antwort habe ich die range
Objekte in list
gewickelt, die eine spürbare Beschleunigung gegeben haben. Als ich jedoch die Anzahl der Iterationen in timeit
erhöhte, bemerkte ich, dass die zeitlichen Unterschiede immer größer wurden. Als Vernunftprüfung habe ich den Slicing durch None
ersetzt, um zu sehen, was passieren würde.
500 Iterationen in timeit
.
c = 1000000
r = list(range(c))
def slow():
for pos in r:
None
ergibt 10.688
und 9.915
sind. Das Ersetzen der for-Schleife durch for pos in islice(r, 0, c, 3)
ergibt 7.626
bzw. 6.270
. Ersetzen von None
durch r[pos]
ergab 20~
bzw. 28~
. r[pos:pos+3]
ergibt 67.531
bzw. 106.784
.
Wie Sie sehen können, sind die Timing-Unterschiede sehr groß. Ich bin immer noch überzeugt, dass das Problem nicht direkt mit range
zusammenhängt.
Haben Sie 'range' oder' xrange' in Python 2 verwendet? – cdarke
Versuchen Sie es erneut mit 'r = list (range (c))'. –
Python 3 'range' und Python 2' xrange' Objekte sind in diesem Kontext nicht ähnlich. Python 3 'range' Objekte unterstützen Slicing, Python 2' xrange' Objekte unterstützen kein Slicen. – cdarke