Frage zu einer Ausgabe von dis.dis.
Verfasst: Montag 8. Januar 2007, 21:32
Fortführung zu den letzten Posts: http://www.python-forum.de/topic-8700.h ... hlight=24h
Der Vollständigkeit halber nochmal erwähnt was wir bisher wissen, weil das folgende darauf aufbaut:
Es ist "evil" in einer schleife folgendes zu machen, weil es durch das ständige Kopieren (dest += srclin) Ineffizient ist (Kostet unnötige Zeit):
Stattdessen sollte man diese Methode nutzen weil dabei das Kopieren entfällt und so Zeit spart. Das verbinden wird einmalig am ende der Schleife gemacht:
Den ``dis.dis`` Output spare ich mir an dieser stelle.
...
Außerhalb wäre 's = ''.join([x, y, z])' langsamer als 's = x + y + z' und würde auch mehr speicher verbrauchen (wirklich mehr speicher verbrauch wegen der angelegten temporären ``list``? {EDIT: Nein, es wird lediglich eine ``list`` angelegt und die Objekte an dem entsprechenden Index referenziert,}). ``dis.dis`` Output ist im anderen Thread der zumindest Zeigt das es schneller geht weil weniger Aufrufe, keine temporäre ``list`` erzeugt werden/wird:
Nun zur eigentlichen Frage:
Nun steht oben das ``s = '%s%s%s' % (x, y, z)`` besser ist als ``s = x + y + z``. Hab mal ``dis.dis`` benutzt.
Meine Interpretation zum ersten Output ab Zeile 10:
``x, y``(18, 21) werden geladen eine BINARY_ADD ausgeführt (24) dann ``z`` (25) geladen und dann auf ``z`` und dem vorherigen Ergebnis wider ein BINARY_ADD ausgeführt (28 ).
Meine Interpretation zum zweiten Output ab Zeile 10:
Erstmal wird ein Call mehr benötigt (18 ), was ja erstmal nichts sagen muss.
``x, y, z`` werden geladen (21, 24, 27) danach wird ein temporäres ``tuple`` erzeugt mit dem Inhalt von ``x, y, z`` (30) und dann der BINARY_MODULO mit ``tuple`` (30) auf ``'%s%s%s'`` (18 ) angewendet.
Was ist nun schneller?
Vom Gefühl her würde ich sagen das dass zweite schneller ist und Speicherschonender als das erste weil, beim ersten zuviel BINARY_ADD durchgeführt werden müssen (Zeit, Speicher) - (probiert mal a + b+ c+ d+ e+ f+ g+ h+ i) - und beim zweiten nur ein ``tuple`` (dessen Inhalt womöglich nur auf x, y, z referenziert und nicht mehr Speicher verbraucht, im Gegensatz zum ersten wo nach jeder Addition Speicher benötigt wird? {EDIT: Wird nur referenziert.}) erzeugt wird, ansonsten nur ``'%s%s%s'`` und ``x, y, z`` geladen werden müssen und als letztes nur eine einmalige Operation ausgeführt werden muss (BINARY_MODULO)
Interpretiere ich das so richtig und habe ich die richtigen Schlüsse daraus gezogen und das zweite ist tatsächlich schneller und Speicherschonender?
lg
sape
EDIT: Einige Fehler beseitigt.
So weit gut und auch verständlich Bis auf die Sache die ich angesprochen habe außerhalb einer Funktion.Whenever joining more than two strings, use string interpolation, not addition:This has to do with efficiency; the intermediate string x+y is made (and thus copied) before x+y+z is made, so it's less efficient. People who use string concatenation in a for loop will be swiftly kicked in the head.Code: Alles auswählen
s = x + y + z # Bad. s = '%s%s%s' % (x, y, z) # Good. s = ''.join([x, y, z]) # Best, but not as general.
Der Vollständigkeit halber nochmal erwähnt was wir bisher wissen, weil das folgende darauf aufbaut:
Es ist "evil" in einer schleife folgendes zu machen, weil es durch das ständige Kopieren (dest += srclin) Ineffizient ist (Kostet unnötige Zeit):
Code: Alles auswählen
dest = ''
source = ['a', 'b', 'c', 'd']
for srclin in source:
dest += srclin
Code: Alles auswählen
dest = list()
source = ['a', 'b', 'c', 'd']
for srclin in source:
dest.append(srclin)
dest = "".join(dest)
...
Außerhalb wäre 's = ''.join([x, y, z])' langsamer als 's = x + y + z' und würde auch mehr speicher verbrauchen (wirklich mehr speicher verbrauch wegen der angelegten temporären ``list``? {EDIT: Nein, es wird lediglich eine ``list`` angelegt und die Objekte an dem entsprechenden Index referenziert,}). ``dis.dis`` Output ist im anderen Thread der zumindest Zeigt das es schneller geht weil weniger Aufrufe, keine temporäre ``list`` erzeugt werden/wird:
Code: Alles auswählen
...
s = x + y + z # Meiner Meinung Besser.
s = ''.join([x, y, z]) # Speicher(?) und Performance Verschwendung!
Nun steht oben das ``s = '%s%s%s' % (x, y, z)`` besser ist als ``s = x + y + z``. Hab mal ``dis.dis`` benutzt.
Code: Alles auswählen
#!/usr/bin/env python # -*- coding: utf-8 -*- from dis import dis def x(): x = 'test1' y = 'test2' z = 'test3' return x + y + z dis(x)
Code: Alles auswählen
7 0 LOAD_CONST 1 ('test1') 3 STORE_FAST 0 (x) 8 6 LOAD_CONST 2 ('test2') 9 STORE_FAST 1 (y) 9 12 LOAD_CONST 3 ('test3') 15 STORE_FAST 2 (z) 10 18 LOAD_FAST 0 (x) 21 LOAD_FAST 1 (y) 24 BINARY_ADD 25 LOAD_FAST 2 (z) 28 BINARY_ADD 29 RETURN_VALUE
Jetzt brauche ich mal Hilfe zur Interpretation des zweiten Outputs ab Zeile 10.Code: Alles auswählen
#!/usr/bin/env python # -*- coding: utf-8 -*- from dis import dis def x(): x = 'test1' y = 'test2' z = 'test3' return '%s%s%s' % (x, y, z) dis(x)
Code: Alles auswählen
7 0 LOAD_CONST 1 ('test1') 3 STORE_FAST 0 (x) 8 6 LOAD_CONST 2 ('test2') 9 STORE_FAST 1 (y) 9 12 LOAD_CONST 3 ('test3') 15 STORE_FAST 2 (z) 10 18 LOAD_CONST 4 ('%s%s%s') 21 LOAD_FAST 0 (x) 24 LOAD_FAST 1 (y) 27 LOAD_FAST 2 (z) 30 BUILD_TUPLE 3 33 BINARY_MODULO 34 RETURN_VALUE
Meine Interpretation zum ersten Output ab Zeile 10:
``x, y``(18, 21) werden geladen eine BINARY_ADD ausgeführt (24) dann ``z`` (25) geladen und dann auf ``z`` und dem vorherigen Ergebnis wider ein BINARY_ADD ausgeführt (28 ).
Meine Interpretation zum zweiten Output ab Zeile 10:
Erstmal wird ein Call mehr benötigt (18 ), was ja erstmal nichts sagen muss.
``x, y, z`` werden geladen (21, 24, 27) danach wird ein temporäres ``tuple`` erzeugt mit dem Inhalt von ``x, y, z`` (30) und dann der BINARY_MODULO mit ``tuple`` (30) auf ``'%s%s%s'`` (18 ) angewendet.
Was ist nun schneller?
Vom Gefühl her würde ich sagen das dass zweite schneller ist und Speicherschonender als das erste weil, beim ersten zuviel BINARY_ADD durchgeführt werden müssen (Zeit, Speicher) - (probiert mal a + b+ c+ d+ e+ f+ g+ h+ i) - und beim zweiten nur ein ``tuple`` (dessen Inhalt womöglich nur auf x, y, z referenziert und nicht mehr Speicher verbraucht, im Gegensatz zum ersten wo nach jeder Addition Speicher benötigt wird? {EDIT: Wird nur referenziert.}) erzeugt wird, ansonsten nur ``'%s%s%s'`` und ``x, y, z`` geladen werden müssen und als letztes nur eine einmalige Operation ausgeführt werden muss (BINARY_MODULO)
Interpretiere ich das so richtig und habe ich die richtigen Schlüsse daraus gezogen und das zweite ist tatsächlich schneller und Speicherschonender?
lg
sape
EDIT: Einige Fehler beseitigt.