BlackJack hat geschrieben:Aufbauen einer Zeichenkette mittels wiederholtem ``+=`` kann recht ineffizient werden. Üblicherweise sammelt man die Einzelteile in einer Liste und benutzt am Ende die `join()`-Methode auf Zeichenketten.
Liest man ja immer wieder. Hab mal experimentiert:
Code: Alles auswählen
import time, profile, cProfile
def string_add():
s = ""
for k in xrange(anz): s+=str(k)
def list_app():
l = list()
for k in xrange(anz): l.append(str(k))
s = "".join(l)
def list_comp():
s = "".join([str(k) for k in xrange(anz)])
anz = 100000 # 100.000
profile.run("string_add(); list_app(); list_comp()")
cProfile.run("string_add(); list_app(); list_comp()")
anz = 1000000 # 1.000.000
for func in [string_add,list_app,list_comp]:
time0 = time.time()
func()
print "%10s: %.2f sec" %(func.__name__,time.time()-time0)
Dabei ist folgendes herausgekommen (gekürzte Fassung):
Code: Alles auswählen
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.316 0.316 0.344 0.344 speedtest.py:12(list_comp)
1 0.284 0.284 0.284 0.284 speedtest.py:3(string_add)
1 1.812 1.812 3.112 3.112 speedtest.py:7(list_app)
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.266 0.266 0.285 0.285 speedtest.py:12(list_comp)
1 0.338 0.338 0.338 0.338 speedtest.py:3(string_add)
1 0.567 0.567 0.805 0.805 speedtest.py:7(list_app)
string_add: 3.56 sec
list_app: 3.71 sec
list_comp: 3.51 sec
Unterschiede in den absoluten Zeiten bei den verschiedenen Testverfahren machen mir kein Problem; aber die relativen Zeiten. Das einzige, was demnach wirklich sicher zu sein scheint, ist, dass die Variante mit dem append() die schlechteste Performance erreicht. Zeichenketten"addition" und LC tun sich wenig. Je nach "Profiler" liegt mal die eine, mal die andere vorne.
Ist mein Testverfahren grundsätzlich unbrauchbar?
Oder ist die Ergebniszeichenkette mit 488890 Zeichen immer noch zu kurz?
Gibt es andere Szenarien, wo eine Zeichenketten"addition" klar verliert?