string interpolation VS. string addition

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Freitag 12. Januar 2007, 15:07

cracki hat geschrieben:sape:

du erzeugst eine riesige source datei anstatt die strings zur laufzeit zu erzeugen. klar brauchts laden da unmengen von zeit.

Ich geb es auf. Du hast es nicht begriffen. :roll: -> Kuckst du Sourcecode!

cracki hat geschrieben:deine benchmarks beruhen auf monstroesen formatstrings. wie waers wenn du kleine formatstrings nimmst, dafuer aber mehrere tausend iterationen misst und dann die zeiten vergleichst?
Es geht nicht darum die Interpolatiosvariante gegen die Additionsvariante in mehreren Tausenden Iterationen zu messen, sondern außerhalb einer schleife. Das was du meinst wurde bereits schon gemacht. Es soll lediglich gemessen werden wie lange ein ``return x + y + z + ...`` braucht und wie lange ``return "%s%s%s ... %(x, y, z ...``. Ist der Quelletext den so unverständlich? Sind meine Erklärungen DEN SO unverständlich??

cracki hat geschrieben:
sape hat geschrieben:
cracki hat geschrieben:dazu kommt, dass du mit python nicht die noetige erfahrung hast. du wuesstest also garnicht, wie du zu benchmarkenden code so schreibst, dass du auch das messen kannst was du willst.
Ich glaube das kannst Du nicht beurteilen, wie viel Erfahrung ich habe.

lieg ich denn sooo falsch mit meiner vermutung?
Ja!
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Freitag 12. Januar 2007, 15:52

blackbird hat geschrieben:
Leonidas hat geschrieben:
birkenfeld hat geschrieben:
cracki hat geschrieben:sape, leider kann ich deine scripts nicht sehen, weil pocoo gerade kaputt ist.


Hu?

Er meint eigentlich LodgeIt. So gibt dieser Link eine ViewDoesNotExist-Exception:


fixed

testcase added
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Freitag 12. Januar 2007, 17:22

sape:
eine "29 MB" grosse .py datei zu erzeugen ist doch schon ein bisschen albern, nicht?
warum wolltest du die strings nicht zur laufzeit erzeugen? waer viel schneller gegangen.
...meh...
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Beitragvon Python 47 » Samstag 13. Januar 2007, 15:17

@Sape:

Glaub mir ich kenn cracki gut genug um beurteilen zu können das er zu 99% Recht mit seinen Posts hat, um es genau zu sagen, habe ich es noch nie erlebt, das cracki falschen/schlechten Source Code gepostet oder in seiner Antwort falsch lag, in diesem, wie auch in anderen Boards.

Und es ist auch sinnlos, dass du mit cracki diskutierst, da er eh Recht hat.

Und woran er es erkennen kann, das du noch nicht viel Erfahrung mit der Sprach hast? Ganz einfach an deinen geposteten Codes.

Das hier soll kein Post sein, der sich gegen Sape richtet.
mfg

Thomas :-)
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Sonntag 14. Januar 2007, 02:24

Python 47 hat geschrieben:Glaub mir ich kenn cracki gut genug um beurteilen zu können das er zu 99% Recht mit seinen Posts hat,
Hab mir seine bisherigen Post durchgelesen. Ich denke die sprechen für sich.

Und um zu beurteilen ob einer zu 99% immer recht hat, muss man entweder genauso gut oder besser sein. Ich kann mir nicht vorstellen, das du oder ich oder sonstwer beurteilen können, das er in jeden Gebiet immer zu 99% Recht hat. Dazu sind die Interessen zu unterschiedlich. Und selbst wenn ihr die gleiche Interessen habt, müsstest du in genau diesen Interesengebieten genauso (oder gar besser) bescheid Wissen um auf so eine Meinung zu kommen.

Ist das der Fall bei dir oder spricht da nur die pure Sympatie aus dir?

Python 47 hat geschrieben:um es genau zu sagen, habe ich es noch nie erlebt, das cracki falschen/schlechten Source Code gepostet

1. Falschen Sourcecode? -> Nein, habe ich auch noch nicht bei ihm gesehen.
2. Unpassenden Sourcecode -> Ja.
3. Schlechten Sourcecode -> Auch ja.

Davon abgesehen habe ich auch schon schlechten und unpassenden (Weil ich einen Post nicht verstanden habe) Code gepostet. Und mal nebenbei: Hier sind viele Python-Profis die auch schon mal schlechten und unpassenden Code gepostet habe, das sich oft erst gegen ende eines Threads ergeben hat ;) Und ich rede hier wirklich von den richtigen Profis ;) -> Niemand ist unfehlbar. Jeder macht Fehler.

Daher würde ich an deiner stelle nicht in seinen Namen Sprechen, da ich glaube das er selber nicht will, dass du eine Meinung über ihn verbreitest die er selber so nicht sehen will. -> So nach dem Motte: "Ich bin unfehlbar" <- Ich glaube kaum das er selber von sich so anmaßend denkt. :)

Python 47 hat geschrieben:oder in seiner Antwort falsch lag, in diesem, wie auch in anderen Boards.
Ich habe es schon erlebt. Und? Ist ja nichts schlimmes. Dagegen ist keiner gewappnet.

Python 47 hat geschrieben:Und es ist auch sinnlos, dass du mit cracki diskutierst, da er eh Recht hat.
Man beachte das Wort "eh" in deinem Satz.

Kannst du das auch begründen warum er eh Recht hat? Kannst du nachvollziehen warum er recht hat? Oder hat er deiner Meinung nach immer Recht, egal was die anderen Sagen? Bist du nicht ein wenig voreingenommen?

Heißt das, egal was cracki sagt, ich habe nicht das Recht mit ihm zu diskutieren, weil er immer Recht hat (Wie gesagt man beachte das Wort "eh" in deinem Satz)? -> Auch hier würde ich dir empfehlen, nicht in seinem Namen so eine Aussage zu machen, da ich mir beim besten willen nicht vorstellen kann das er möchte das du so einen scheiß über ihm verbreitest. Den ich glaube kaum das cracki sich als einen Menschen sieht der immer (oder ehe ;)) recht hat.

Python 47 hat geschrieben:Und woran er es erkennen kann, das du noch nicht viel Erfahrung mit der Sprach hast? Ganz einfach an deinen geposteten Codes.
Woher weißt du das er genau dass als Grundlage genommen hat? Er hat doch schon angefangen über da Thema zu reden und sich eine "Meinung" gebildet (basierend auf einem Vorurteil), bevor er meinen Code gelesen hat, und nebenbei bemerkt, bevor er meine Post richtig gelesen hatte. Erst später, nach dem er das erledigt hatte, war eine vernümftige Diskussion möglich, da er sich mit den Code und den Fakten auseinander gesetzt hatte. Aber davor, war das nur eine Wertung ohne jeglicher Grundlage (Vorurteil), da er sich nicht die Mühe gemacht hatte vorab erstmal alles zu Analysieren, bevor er eine Behauptung aufstellt (Was sehr unprofessionelle ist.).

Python 47 hat geschrieben:Das hier soll kein Post sein, der sich gegen Sape richtet.

Okay, eigentlich wollte ich folgendes nicht schreiben. Aber da Du nun mit diesem Satz "Subtil" damit anfängst in dem Du extra betonst dass sich dein Post nicht gegen mich richtet, kann ich nur davon ausgehen dass der Post genau das bezwecken soll, da man sowas nicht extra erwähnen braucht, wenn es nicht der Fall ist. = Wenn sich der Post nicht gegen mich richten würde dann bräuchtest du das auch nicht zu erwähnen, was du aber nun gemacht hast.

Du sagst der Post richtet sich nicht gegen mich. Ich sage, doch soll es und ich weiß auch warum ;) Es geht um die Differenz die wir beiden hatten, die vor dem öffnen diese Threads zwischen uns begann. Daher schlage ich dir vor, dass wir unsere Differenzen per PN oder ICQ aus der Welt schaffen und uns nicht auf so ein Niveau herablassen. Was hältst du davon? :) Es kann ja nicht angehen, das du jetzt anfängst in jeden Thread in dem ich poste, etwas zu schreiben das sich gegen mich richtet, nur weil du dich unberechtigterweise von mir angepisst gefühlt hast ;) Und ehrlich, ich habe auch keine Lust drauf da mitzumachen. Aus dem Alter bin ich lägst raus.

Ich könnte dich Ignorieren. Wahrlich, das wäre das einfachste. Da ich aber kein Mensch bin der andere Ignoriert (da ich sowas echt scheiße finde), würde ich lieber erst Probieren unsere Streitigkeiten wie Erwachsene Menschen zu klären.

Daher las uns unseren Disput, in einem privaten klärenden Gespräch, aus der Welt schaffen. Alles andere führt zu nichts.

lg
sape

P.S.: Danke fürs zuhören.
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Sonntag 14. Januar 2007, 12:22

cracki hat geschrieben:sape:
eine "29 MB" grosse .py datei zu erzeugen ist doch schon ein bisschen albern, nicht?
warum wolltest du die strings nicht zur laufzeit erzeugen? waer viel schneller gegangen.

wenn du mir das sagen koenntest, dann waer schon viel geschafft.
...meh...
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Montag 15. Januar 2007, 10:55

nun denn, erklaer doch bitte mal, warum du eine 29MB grosse .py datei brauchst, um ein benchmark zwischen interpolation und + von strings zu testen.
...meh...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Montag 15. Januar 2007, 11:18

Hab ich nicht gesagt das ich das brauche. Bei ``MAX_OBJ=1000`` ist ``output.py`` 2.79MB groß. Bei ``MAX_OBJ=100`` 285KB.

Je nach dem wie viele Elemente drin sind um so größer ist die Datei.

Aber mal was grundsätzliches:
Du willst das ja in einer iteratieven Variante testen. Als inerhalb einer Schleife und willst dafür kurze Strings verwenden bzw. nur einen String.

Code: Alles auswählen

str_ = "0" * 80
max_iter = 10000
# Additivevariante
def f1():
    for i in range(max_iter):
        tmp = str_ + str_

#Interpolierendevariante
def f2():
     for i in range(max_iter):
        tmp = "%s%s" % (str_, str_)


Sehe ich das so richtig?

Wenn ja, da ist das was völlig anderes als ich testen wollte. Was ich testen wollte habe ich ja nun zur genüge geschrieben.

Aber für dich nochmal:
Ich will testen wie lange ein return bei z.B. 10.000 Stings in der ``+`` variante dauert und wie lange ein return in der ``%`` Variante dauert. Da das ganze Flexible sein soll (also das ich die Anzahl der Objekte bestimmte kann) habe ich dafür ein script geschriben, das mir die Entsprechen Datei erzeugt.

Also simpel gesagt: Ich will nur wissen wie lange es dauert z.B. 10.000 Strings in der ``+`` Variante zu "verbinden" und in der ``%`` Variante. Mehr nicht.

So, noch was: Das die Scripts noch nicht Optimal sind weiß ich. Das kann man verbessern, aber nicht in dem du mir etwas vorschlägst das was ganz anderes testet.

Wie würdest du das finden?

Code: Alles auswählen

str_ = "blubb"
def f1():
    return str_ + str_ + ... + N

def f2():
    return "%s%s%s ... N %(str_, str_, ... N


So eine Datei müsste natürlich auch automatisch generiert werden, da ich ja die anzahl der Objekte die mit einander verbunde werden sollen bestimmen will. (Daher auch das große N das es andeuten soll).

Damit würde die Liste wegfallen und die ``output.py`` nicht mehr so groß werden. Am Messergebnis würde sich aber nur geringfügig was ändern.

lg
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Montag 15. Januar 2007, 11:35

Code: Alles auswählen

foostr = "a" * 1000 # oder sonst ein string

def test1(N):
    res = ""
    t = time.clock()
    for i in xrange(N):
        res += foostr
    return time.clock() - t

def test2(N):
    fmtstr = "%s" * N
    args = tuple([foostr] * N)
    t = time.clock()
    fmtstr % args
    return time.clock() - t

N = 5000
print "+ test:", test1(N)
print "% test:", test2(N)


das meine ich
das ding braucht fuer 10000 elemente keine ewigkeit beim laden, und es benchmarkt ebenfalls + und % auf strings.
Zuletzt geändert von cracki am Montag 15. Januar 2007, 11:41, insgesamt 1-mal geändert.
...meh...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Montag 15. Januar 2007, 11:40

cracki hat geschrieben:

Code: Alles auswählen

foostr = "a" * 1000 # oder sonst ein string

def test1(N):
    res = ""
    t = time.clock()
    for i in xrange(N):
        res += foostr
    return time.clock() - t

def test2(N):
    fmtstr = "%s" * N
    t = time.clock()
    fmtstr % tuple([foostr] * N)
    return time.clock() - t

print "+ test:", test1(1000)
print "% test:", test2(1000)


das meine ich


Sorry aber da sich ja echt :lol:. Sage ich doch die ganze Zeit das du nicht verstanden hast was ich machen wollte ;) Du testest da was völlig anderes als ich testen wollte.

BTW: ``test2`` geht noch einigermaßen. Aber ``test1`` ist völlig daneben und macht genau das was ich nicht testen wollte -> Test einer Additivevariante in einer iterativen-Methode.

Nichts für ungut.

lg
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Beitragvon Luzandro » Montag 15. Januar 2007, 11:41

cracki hat geschrieben:

Code: Alles auswählen

foostr = "a" * 1000 # oder sonst ein string

def test1(N):
    res = ""
    t = time.clock()
    for i in xrange(N):
        res += foostr
    return time.clock() - t

def test2(N):
    fmtstr = "%s" * N
    args = tuple([foostr] * N)
    t = time.clock()
    fmtstr % args
    return time.clock() - t

print "+ test:", test1(1000)
print "% test:", test2(1000)


das meine ich


Das ist allerdings tatsächlich etwas anderes, als er gemeint hat - im übrigen kann man für sowas das timeit-modul verwenden, was auch gleich die vielen iterationen erledigt und den GC deaktiviert:

Code: Alles auswählen

import timeit

a = "foo"
b = "bar"
c = "HURZ"

setup = "from __main__ import a,b,c"

print timeit.Timer('a+b+c', setup).timeit()


Edit (Leonidas): Code-Highlighting aktiviert.
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Montag 15. Januar 2007, 11:47

sape hat geschrieben:Du testest da was völlig anderes als ich testen wollte.

BTW: ``test2`` geht noch einigermaßen. Aber ``test1`` ist völlig daneben und macht genau das was ich nicht testen wollte -> Test einer Additivevariante in einer iterativen-Methode.


und was ist der unterschied, abgesehen davon dass deine variante ein grosses "foo+foo+foo+...+foo" ist und meine dazu eine schleife benutzt?
in beiden varianten wird immer wieder ein neuer string erzeugt, auf den dann wieder addiert wird usw... die laufzeit in beiden varianten wird von der stringerzeugung dominiert.
was soll da anders sein?
...meh...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Montag 15. Januar 2007, 12:05

cracki hat geschrieben:
sape hat geschrieben:Du testest da was völlig anderes als ich testen wollte.

BTW: ``test2`` geht noch einigermaßen. Aber ``test1`` ist völlig daneben und macht genau das was ich nicht testen wollte -> Test einer Additivevariante in einer iterativen-Methode.


und was ist der unterschied, abgesehen davon dass deine variante ein grosses "foo+foo+foo+...+foo" ist und meine dazu eine schleife benutzt?
in beiden varianten wird immer wieder ein neuer string erzeugt, auf den dann wieder addiert wird usw... die laufzeit in beiden varianten wird von der stringerzeugung dominiert.
was soll da anders sein?


Naja, Z.B. setzt du das, was du in der ``+`` Variante nutzt, nicht auch in der ``%`` Variante fort, da du in der ``%`` Variante auf eine Schleife verzichtest. Das heißt, das dass Messergebnis immer zu ungenau sein wird, weil bei deiner ``+`` eine schleife genutzt wird, die unnötigen "Overhead" verursacht. Davon mal abgesehen, ist in beiden Funktionen zuviel Code drumherum (Unterschiedlicher Code) der das Messergebnissen nicht genauer macht, sondern im gegenteil sogar mehr verfälscht.

Meine Methode ist zwar nicht die "Speicherschonenste", aber dafür am "genausten". Den die machen genau nur das, was ich ja auch testen wollte und haben nicht unnötigen Code drumherum der das Ergebnis noch mehr verfälscht.

EDIT: Angenommen die ``+`` Variante und ``%`` Variante wären gleich schnell (Fluktuationen mit eingerechnet), dann würde bei deinem Testverfahren die ``+`` Variante immer den Kürzeren ziehen, weil dort mehr "overhead" erzeugt wird.
BlackJack

Beitragvon BlackJack » Montag 15. Januar 2007, 13:05

cracki hat geschrieben:und was ist der unterschied, abgesehen davon dass deine variante ein grosses "foo+foo+foo+...+foo" ist und meine dazu eine schleife benutzt?


Genau das ist da anders. In Deinem Code ist eine Schleife und die Implementierung der Operatoren ``+`` und ``+=`` ist nicht zwingend die selbe, soll heissen ``a += b`` führt nicht in jedem Fall das gleiche aus wie ``a = a + b``. Wobei bei beiden Schreibweisen für jedes Zwischenergebnis auch eine Zuweisung an `a` durchgeführt wird, die auch Zeit kostet.
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Montag 15. Januar 2007, 13:13

sape:
du weisst, was laufzeitkomplexitaet bedeutet und wie man diese ermittelt?
also konstant, logarithmisch, linear, polynomial, exponential, faktorial...

blackjack:
__add__ von strings ist doch fuer 2 operanden (links und rechts) definiert. also kann schon mal eine optimierung fuer mehrfache addition nicht wahrscheinlich sein (ich werde jetzt nicht nachschauen, ob python da magic macht und sich ueber string.__add__ hinwegsetzt).
dann waere idealerweise ein `a += b` schneller als ein `a = a + b`, denn dann koennte evtl einfach an a angehaengt werden, wenn der speicher noch alloziiert ist.

wie solls also schneller gehen? a+a+a ist nichts anderes als x += a im loop.

iteration ist auch nix anderes als lineare rekursion, mit dem unterschied dass in primitiven sprachen jede lineare rekursion den stack zum wachsen bringt, was natuerlich genau wie iteration vernachlaessigbar wenig zeit verbraucht.

die laufzeit des loops ist linear und vernachlaessigbar. wenns sein muss kann man das sogar rausrechnen mit nem leeren loop...
Zuletzt geändert von cracki am Montag 15. Januar 2007, 13:31, insgesamt 1-mal geändert.
...meh...

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder