Strings verketten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo,

ich hab mal getestet, wie man Strings am besten verkettet. Es gibt da ja die Möglichkeit mit + oder mit % oder auch ein join.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import time

alpha = "alpha"
beta  = "beta"
gamma = "gamma"
delta = "delta"
num = 1000000

print "Teste +"
t = time.clock()
for i in xrange(num):
    tmp = alpha+beta+gamma+delta
print "%.3f" % (time.clock()-t)
print "Teste join liste"
words = [alpha, beta, gamma,delta]
t = time.clock()
for i in xrange(num):
    tmp = "".join(words)
print "%.3f" % (time.clock()-t)
print "Teste join tuple"
words = (alpha, beta, gamma,delta)
t = time.clock()
for i in xrange(num):
    tmp = "".join(words)
print "%.3f" % (time.clock()-t)
print "Teste %"
t = time.clock()
for i in xrange(num):
    tmp = "%s%s%s%s" % words
print "%.3f" % (time.clock()-t)
print "Teste % mit dict"
words = dict(zip(["a", "b", "c", "d"], words))
t = time.clock()
for i in xrange(num):
    tmp = "%(a)s%(b)s%(c)s%(d)s" % words
print "%.3f" % (time.clock()-t)
Natürlich hängt das Ergebnis auch von der Anzahl der zu verketteten Strings ab, bei nur zwei Strings ist + am schnellsten. Interessanter weise aber schneidet bei 4 Strings der %-Operator besten ab. Sind noch mehr Strings zu verketten ist join mit einer Liste am schnellsten, aber immer dicht gefolgt von %-Operator mit einem Tuple. % mit einem Dictionary ist erwartugnsgemäss am langsamsten, hat aber andere Vorteile.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

wenn ich mich nicht irre und verständnisprobs hab, hab ich eben gelernt, dass strings auch objekte sind?!? :?:

hui...gut zu wissen :D

mfg Olf
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Was sollen sie denn sonst sein :shock: :?: ? Eigentlich sind sie C-Objecte mit einem Wrapper drum herum, der sie für Python kompatibel macht und den Typ(!) str wie eine Pythonklasse aussehen lässt und verhalten lässt.

@Dookie: du könntest dein Code wesentlich einfacher mit dem Modul timeit bauen :wink: .
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Dookie hat geschrieben:ich hab mal getestet, wie man Strings am besten verkettet. Es gibt da ja die Möglichkeit mit + oder mit % oder auch ein join.
Du hast wohl ehr getestet, welches am schnellsten funktioniert... Ich hab mir mittlerweile zum Grundsatz gemacht, ehr so zu programmieren, daß der Quellencode am einfachsten zu verstehen ist... Auch wenn das ehr mehr Code und ehr langsamer ist... :)

Aber dennoch interressant, dein test! :lol:
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi genrich,

manchmal kommt man ums optimieren nicht rum, siehe auch mein XML_Objects, wo ich durch Optimierung eine Geswindigkeitssteigerung von bis zu 100x bei sehr vielen Objekten beim speichern erreicht habe.
Allein die Verwendung von % anstatt + beim XML-Strings zusammensetzen hat 20% Geschwindigkeitszuwachs gebracht.

Also lieber in Python optimieren als in C++ coden ;)


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Hallo,

@genrich: Klar ist Lesbarkeit auch wichtig, aber manchmal entscheidet die Ausführgeschwindigkeit nicht nur, ob man sehr kurz oder kurz warten muß, sondern ob ein Projekt überhaupt machbar ist. Ich habe Python auch schon im CAAD-Bereich eingesetzt, wo die Datenmengen manchmal ziemlich explodieren. Der eigentliche Anlaß für die Optimierung von Dookie war ein quadratisches Zeitverhalten seines Moduls, was er in ein lineares Verhalten umwandeln konnte.

Angenommen, eine Operation dauert 1s, und nun erhöht man die Datenmenge mal um den Faktor 300, gerade bei 3D-Daten geht das ganz schnell. Statt 5 min (linear) müßte man bei einer quadratischen Charakteristik jetzt über einen Tag warten.
Das wäre dann u.U. nicht nur unschön, sondern einfach nicht mehr handhabbar -> Projekt gestorben!

@Dookie: Kennst Du schon http://xmlobject.base-art.net/ ? Wenn Namen und Zweck zweier Pakete zu ähnlich sind, gibt es leicht Verwirrung.

Grüße aus Berlin!

Jörg
"Sie sind nicht berechtigt, unrechtmäßige Kopien dieses Datenträgers zu erstellen." - Microsoft-Weisheit auf einer CD von MS-VisualC++-6.0
oenone
User
Beiträge: 75
Registriert: Mittwoch 27. August 2003, 14:39
Wohnort: 49°17'28N, 8°15'57E
Kontaktdaten:

es haengt wohl ausserdem noch vom eingesetzten Betriebssystem ab.

Code: Alles auswählen

$ python -V
Python 2.3.3
$ ./stringtest.py
Teste +
4.140
Teste join liste
4.410
Teste join tuple
4.940
Teste %
4.570
Teste % mit dict
6.330
Bei mir (OpenBSD) ist eindeutig der + auch bei 4 strings am schnellsten.

auf bald
oenone

[edit]
habs mal bei nem freund auf seinem gentoo rechner laufen lassen:

Code: Alles auswählen

$ python -V
Python 2.3.4
$ ./stringtest
Teste +
8.220
Teste join liste
7.100
Teste join tuple
9.330
Teste %
10.400
Teste % mit dict
15.280
hier scheint join mit liste am schnellsten zu sein.
if you don't remember something, it never happened.
if you aren't remembered, you never existed.
i don't quite understand what love is like... but if there was someone who liked me, i'd be happy.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

oenone hat geschrieben:es haengt wohl ausserdem noch vom eingesetzten Betriebssystem ab.
Um es unnötig kompliziert zu machen :lol: Mann könnte ja bei Laufzeit testen, welches Verfahren am schnellsten ist, und dann nur dieses benutzten... :?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi,

bei mir lief der Test unter Debian-Linux mit Python 2.3.4 auf einem Pentium 4. Eventuell hat der Prozessor auch noch Einfluss auf das Ergebnis.
Jedenfalls hat die Verwendung vom % operator keine gravierenden Nachteile egenüber der Verkettung von strings mit anderen Methoden. Und lesbarer finde ich es auch als eine lange kette mit +.

@joerg:
danke für den link, dann werd ich mein Modul wohl umbenennen müssen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Wie sieht es mit der Geschwindigkeit aus, wenn man cStringIO verwendet?

Code: Alles auswählen

from cStringIO import StringIO
def verkette(*texte):
    buf=StringIO()
    buf.writelines(texte)
    return buf.getvalue()
Das dürfte doch für recht viele String rel. schnell sein, oder?
oenone
User
Beiträge: 75
Registriert: Mittwoch 27. August 2003, 14:39
Wohnort: 49°17'28N, 8°15'57E
Kontaktdaten:

wow... dieses cStringIO teil braucht locker 5-6 mal so lang o_O

auf bald
oenone
if you don't remember something, it never happened.
if you aren't remembered, you never existed.
i don't quite understand what love is like... but if there was someone who liked me, i'd be happy.
Antworten