Y0Gi hat geschrieben:[...]
Also hier: Nicht mit einem leeren String beginnen und immer etwas "anfügen" (Strings sind immutable/atomic, müssen also immer kopiert und neu erzeugt werden!), sondern eine Liste füllen und diese am Ende anhand von Zeilenumbrüchen, Kommata oder sonstwas per join() zusammenfügen.
Weis ich doch. Das mit dem...
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
str_ = "Hello Memory ^^"
mem_killer = ''
while True:
mem_killer += str_
print mem_killer
...war auch nur ein Beispiel wie so ein Mem-Killer zustande kommen kann. Auch das man Kontaktion nicht in Schleifen benutzen soll weiß ich und das man stattdessen alles in einer Liste pusht und dann das Ergebnis mit ``"".join`` "verbindet". Oder meintest du mich garnicht?
Aber folgendes ist übertrieben,:
Code: Alles auswählen
s = x + y + z # Bad.
s = ''.join([x, y, z]) # Best, but not as general.
x + y + z wird verbunden und an den namen ``s`` gebunden.
[x, y, z] fügt den Inhalt der drei strings in eine temporäre Liste die dann mit ``join`` zu einem string verbunden wird. Das ist langsamer außerhalb einer schleife. Außerdem ist es speicherintensiver weil erstmal Werte die schon vorhanden sind, extra nochmal in eine temporäre Liste kopiert werden müssen (Redundanter Content).
Hier der Beweis:
Join + temp mem.
Code: Alles auswählen
import dis
def x():
x = 'test1'
y = 'test2'
z = 'test3'
return "".join([x, y, z])
dis.dis(x)
Output:
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 ('')
21 LOAD_ATTR 0 (join)
24 LOAD_FAST 0 (x)
27 LOAD_FAST 1 (y)
30 LOAD_FAST 2 (z)
33 BUILD_LIST 3
36 CALL_FUNCTION 1
39 RETURN_VALUE
Code: Alles auswählen
import dis
def y():
x = 'test1'
y = 'test2'
z = 'test3'
return x + y + z
dis.dis(y)
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
Folgender Teil ist daran interessant:
Erstmal wird die Konstante '' erzeugt (18 ). Dan wird ``join, x, y, z`` geladen (21, 24, 27, 30). Dan _wird_ eine Liste erzeugt (33) in dem x, y, z landen. Danach wird ``join`` aufgerufen (36).
Code: Alles auswählen
18 LOAD_CONST 4 ('')
21 LOAD_ATTR 0 (join)
24 LOAD_FAST 0 (x)
27 LOAD_FAST 1 (y)
30 LOAD_FAST 2 (z)
33 BUILD_LIST 3
36 CALL_FUNCTION 1
Hier wird lediglich ``x, y`` geladen und dann "addiert" und dessen Ergebnis mit ``z`` "addiert" was wesentlich schneller geht, als das oben
Code: Alles auswählen
18 LOAD_FAST 0 (x)
21 LOAD_FAST 1 (y)
24 BINARY_ADD
25 LOAD_FAST 2 (z)
28 BINARY_ADD
Ich glaube man kanns erkenne.
In einer schleife ist es aber klar, das man alles in einer Liste pushen soll die am ennde der schleife mit ``join`` kontaktiert wird. Aber außerhalb siehst du ja selber was rauskommt. EDIT: Besonders wenn die Werte (in dem Fall x, y und z) ehe schon vorliegen ist es Schwachsinn extra redundanten Content zu erzeugen durch sowas. In dem Punkt hat sich der schreiber des Artikels klar geirrt und nicht zu ende gedacht.
lg
EDIT: Text Hinzugefügt.
EDIT2: Erklärung hinzugefügt.