Seite 1 von 1

Strings verketten

Verfasst: Sonntag 1. August 2004, 18:33
von Dookie
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

Verfasst: Sonntag 1. August 2004, 19:11
von DER Olf
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

Verfasst: Sonntag 1. August 2004, 20:59
von Milan
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: .

Re: Strings verketten

Verfasst: Sonntag 1. August 2004, 22:16
von genrich
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:

Verfasst: Sonntag 1. August 2004, 22:36
von Dookie
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

Verfasst: Montag 2. August 2004, 08:29
von joerg
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

Verfasst: Montag 2. August 2004, 11:17
von oenone
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.

Verfasst: Montag 2. August 2004, 11:37
von genrich
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... :?

Verfasst: Montag 2. August 2004, 12:52
von Dookie
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

Verfasst: Montag 2. August 2004, 12:56
von Milan
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?

Verfasst: Montag 2. August 2004, 13:19
von oenone
wow... dieses cStringIO teil braucht locker 5-6 mal so lang o_O

auf bald
oenone