Vor kurzem habe ich angefangen, Python3 zu verwenden, und es fehlt xrange weh.
Einfaches Beispiel:
1) Python2:
from time import time as t
def count():
st = t()
[x for x in xrange(10000000) if x%4 == 0]
et = t()
print et-st
count()
2) Python3:
from time import time as t
def xrange(x):
return iter(range(x))
def count():
st = t()
[x for x in xrange(10000000) if x%4 == 0]
et = t()
print (et-st)
count()
Die Ergebnisse sind jeweils:
1) 1,53888392448 2) 3,215819835662842
Warum ist das so? Ich meine, warum wurde xrange entfernt? Es ist so ein tolles Werkzeug zum Lernen. Für die Anfänger, genau wie ich, als wären wir alle irgendwann. Warum es entfernen? Kann mich jemand auf den richtigen PEP hinweisen, ich kann ihn nicht finden.
Prost.
python
python-3.x
pep
xrange
Katalesie
quelle
quelle
range
in Python 3.x istxrange
von Python 2.x. Es war tatsächlich Python 2.x,range
das entfernt wurde.time
. Abgesehen davon, dass es einfacher zu bedienen und schwerer zu verwechseln ist und Tests für Sie wiederholt,timeit
kümmert es sich um alle möglichen Dinge, an die Sie sich nicht erinnern oder die Sie nicht einmal wissen (wie das Deaktivieren des GC), und verwendet möglicherweise a Uhr mit tausendfach besserer Auflösung.range
aufx%4 == 0
? Warum nicht einfach testenlist(xrange())
vs.list(range())
, damit so wenig Fremdarbeit wie möglich geleistet wird? (Woher wissen Sie zum Beispiel, dass 3.x nichtx%4
langsamer arbeitet?) Warum bauen Sie eine riesige Datei auflist
, die eine Menge Speicherzuweisung erfordert (die nicht nur langsam ist, sondern auch unglaublich variabel) ? ?iter(range)
ist redundant.list(range(..))
. Dies entspricht der Reichweite von Python 2. Oder anderslist(range)
ausgedrückt: xrange wurde in range umbenannt, da dies die bessere Standardeinstellung ist. Es war nicht notwendig, beides zu haben, wenn Sie wirklich eine Liste brauchen. .Antworten:
Einige Leistungsmessungen verwenden,
timeit
anstatt zu versuchen, dies manuell zu tuntime
.Zunächst Apple 2.7.2 64-Bit:
Jetzt python.org 3.3.0 64-Bit:
Offenbar 3.x
range
ist wirklich ein bisschen langsamer als 2.xxrange
. Und diexrange
Funktion des OP hat nichts damit zu tun. (Kein Wunder, da ein einmaliger Anruf an den__iter__
Slot unter 10000000 Anrufen für alles, was in der Schleife passiert, wahrscheinlich nicht sichtbar ist, aber jemand hat ihn als Möglichkeit angesprochen.)Aber es ist nur 30% langsamer. Wie wurde das OP 2x so langsam? Wenn ich die gleichen Tests mit 32-Bit-Python wiederhole, erhalte ich 1,58 gegenüber 3,12. Ich vermute also, dass dies ein weiterer Fall ist, in dem 3.x für 64-Bit-Leistung in einer Weise optimiert wurde, die 32-Bit-Leistung beeinträchtigt.
Aber ist das wirklich wichtig? Überprüfen Sie dies mit 3.3.0 64-Bit erneut:
Das Erstellen von
list
dauert also mehr als doppelt so lange wie die gesamte Iteration.Und was "verbraucht viel mehr Ressourcen als Python 2.6+" betrifft, so sieht es aus meinen Tests so aus, als ob ein 3.x
range
genau die gleiche Größe wie ein 2.x hatxrange
- und selbst wenn es 10x so groß wäre, die unnötige Liste erstellt ist immer noch ungefähr 10000000x mehr ein Problem als alles, was die Bereichsiteration möglicherweise tun könnte.Und was ist mit einer expliziten
for
Schleife anstelle der C-Schleife im Innerendeque
?Es wurde also fast so viel Zeit in der
for
Aussage verschwendet wie in der eigentlichen Arbeit der Iteration derrange
.Wenn Sie sich Gedanken über die Optimierung der Iteration eines Bereichsobjekts machen, suchen Sie wahrscheinlich an der falschen Stelle.
In der Zwischenzeit fragen Sie immer wieder, warum
xrange
entfernt wurde, egal wie oft Ihnen die Leute dasselbe sagen, aber ich werde es noch einmal wiederholen: Es wurde nicht entfernt: Es wurde umbenannt inrange
und das 2.xrange
wurde entfernt.Hier ist ein Beweis dafür, dass das 3.3-
range
Objekt ein direkter Nachkomme des 2.x-xrange
Objekts (und nicht der 2.x-range
Funktion) ist: die Quelle für 3.3range
und 2.7xrange
. Sie können sogar den Änderungsverlauf sehen (der meiner Meinung nach mit der Änderung verknüpft ist, die die letzte Instanz der Zeichenfolge "xrange" an einer beliebigen Stelle in der Datei ersetzt hat).Warum ist es langsamer?
Zum einen haben sie viele neue Funktionen hinzugefügt. Zum anderen haben sie überall alle Arten von Änderungen vorgenommen (insbesondere innerhalb der Iteration), die geringfügige Nebenwirkungen haben. Und es gab viel Arbeit, um verschiedene wichtige Fälle dramatisch zu optimieren, auch wenn es manchmal weniger wichtige Fälle leicht pessimiert. Addiere das alles und ich bin nicht überrascht, dass das Iterieren eines
range
so schnellen wie möglich jetzt etwas langsamer ist. Es ist einer dieser weniger wichtigen Fälle, auf die sich niemand jemals genug konzentrieren würde. Es ist wahrscheinlich, dass niemand jemals einen realen Anwendungsfall hat, bei dem dieser Leistungsunterschied der Hotspot in seinem Code ist.quelle
range
. Dasrange
Objekt in 3.3 ist ein direkter Nachkomme desxrange
Objekts in 2.7, nicht derrange
Funktion in 2.7. Es ist wie zu fragen, währenditertools.imap
zugunsten von entfernt wurdemap
. Es gibt keine Antwort, weil so etwas nicht passiert ist.range
Weile zu iterieren und nichts anderes zu tun.Python3 Palette ist xrange des Python2. Es ist nicht erforderlich, einen Iter darum zu wickeln. Um eine aktuelle Liste in Python3 zu erhalten, müssen Sie verwenden
list(range(...))
Wenn Sie etwas möchten, das mit Python2 und Python3 funktioniert, versuchen Sie dies
quelle
range
undxrange
sich unterschiedlich verhält. Es reicht nicht aus, dies zu tun, man müsste auch sicherstellen, dass man niemals davon ausgeht, dassrange
eine Liste zurückgegeben wird (wie es in Python 2 der Fall wäre).futurize
Tool, mit dem Sie IhrenDer
range
Typ von Python 3 funktioniert genauso wie der von Python 2xrange
. Ich bin mir nicht sicher, warum Sie eine Verlangsamung sehen, da der von Ihrerxrange
Funktion zurückgegebene Iterator genau das ist, was Sie erhalten würden, wenn Sierange
direkt iterieren würden .Ich kann die Verlangsamung auf meinem System nicht reproduzieren. So habe ich getestet:
Python 2, mit
xrange
:Python 3 mit
range
ist ein kleines bisschen schneller:Ich habe kürzlich erfahren, dass der
range
Typ von Python 3 einige andere nette Funktionen hat, wie zum Beispiel die Unterstützung für das Schneiden:range(10,100,2)[5:25:5]
isrange(20, 60, 10)
!quelle
xrange
so oft von der Suche nach dem Neuen , oder wird das nur einmal gemacht?xrange
wurde nicht entfernt, nur umbenannt .range
ist für mich die konstante Zeit__contains__
. Neulinge schrieben früher300000 in xrange(1000000)
und das führte dazu, dass das Ganzexrange
(oder zumindest die ersten 30%) wiederholt wurde. Deshalb mussten wir erklären, warum das eine schlechte Idee war, obwohl es so pythonisch aussieht. Nun, es ist pythonic.Eine Möglichkeit, Ihren Python2-Code zu reparieren, ist:
quelle
range = xrange
wie im Kommentar von @John La Royxrange = range
... ich habe die Aussagen gewechseltxrange aus Python 2 ist ein Generator und implementiert einen Iterator, während range nur eine Funktion ist. In Python3 weiß ich nicht, warum der Bereich entfernt wurde.
quelle
range()
das Äquivalent von PY2 istxrange()
. Und somit ist in PY3xrange()
überflüssig.comp: ~ $ python Python 2.7.6 (Standard, 22. Juni 2015, 17:58:13) [GCC 4.8.2] unter Linux2
5.656799077987671
5.579368829727173
21.54827117919922
22.014557123184204
Mit timeit number = 1 param:
0,2245171070098877
0,10750913619995117
comp: ~ $ python3 Python 3.4.3 (Standard, 14. Oktober 2015, 20:28:29) [GCC 4.8.4] unter Linux
9.113872020003328
9.07014398300089
Mit timeit number = 1,2,3,4 arbeitet param schnell und linear:
0,09329321900440846
0,18501482300052885
0,2703447980020428
0,36209142999723554
Wenn wir also einen laufenden Schleifenzyklus wie timeit.timeit messen ("[x für x im Bereich (1000000) wenn x% 4]", Zahl = 1) (wie wir es tatsächlich in echtem Code verwenden), funktioniert python3 schnell genug. aber in wiederholten Schleifen gewinnt Python 2 xrange () in der Geschwindigkeit gegen range () von Python 3.
quelle