Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Schnelles "Addieren" von Strings
WeBsPaCe - Mo 28.04.08 12:47
Titel: Schnelles "Addieren" von Strings
Tach, ;-)
Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
var ig: Integer; ws: WideString; dt: TDateTime;
begin ws := ''; while True do begin dt := NOW; for ig := 0 to 500 do ws := ws + 'foo'; WriteLn(FormatDateTime('SS.ZZZ', NOW - dt)); end; end. |
Ich bekomm mit der Zeit immer größere Differenzen. Vermutung: da
ws immer größer wird, dauert die Addition
ws + 'foo' immer länger.
Was also tun? Denn prinzipiell stell ich mir das doch nicht falsch vor, dass die Operation immer dieselbe ist, also nicht länger dauern sollte/dürfte.
Danke schonmal, bis dann,
WeBBy
Tilo - Mo 28.04.08 13:10
Ich denke das liegt am Typ Widestring. Dieser kann bis zu 2GB(Rad Studio 2007) groß werden. Wenn Du nun den String erweiterst und er nicht mehr an die Speicherstelle passt wo er im Moment steht so muss er an eine andere Stelle kopiert werden was Zeit benötigt. Und je länger der String ist desto mehr muss kopiert werden.
Und ich schätze es kommt noch etwas anderees hinzu: Du fügst nicht einfach nur an, sondern Du weist der StringVariable immer einen neuen Wert zu. Es wird der alte Wert eingelesen, der neue Teilstring addiert und dann das Ergebniss der Variablen zugewiesen.
Wenn es nicht so ist bitte ich um Korrektur.
WeBsPaCe - Mo 28.04.08 13:17
Tach! :-)
Tilo hat folgendes geschrieben: |
| Ich denke das liegt am Typ Widestring. Dieser kann bis zu 2GB(Rad Studio 2007) groß werden. Wenn Du nun den String erweiterst und er nicht mehr an die Speicherstelle passt wo er im Moment steht so muss er an eine andere Stelle kopiert werden was Zeit benötigt. Und je länger der String ist desto mehr muss kopiert werden. |
Okay, aber das Problem hab ich doch in jedem Fall, oder? Auch bei einem String, wird der ab einer gewissen Größe nicht mehr da hinpassen, wo er war. Oder nicht?
Tilo hat folgendes geschrieben: |
| Und ich schätze es kommt noch etwas anderees hinzu: Du fügst nicht einfach nur an, sondern Du weist der StringVariable immer einen neuen Wert zu. Es wird der alte Wert eingelesen, der neue Teilstring addiert und dann das Ergebniss der Variablen zugewiesen. |
Genau, das mein ich auch. Eine Idee, wie ich das anders realisieren kann?
MfG,
WeBBy
alzaimar - Mo 28.04.08 13:30
Titel: Re: Schnelles "Addieren" von Strings
WeBsPaCe hat folgendes geschrieben: |
| ... dass die Operation immer dieselbe ist, also nicht länger dauern sollte/dürfte. |
Nein! Wie schon erwähnt, wird der String immer länger. Leere den String also vor der For-Schleife und dann sollte das zu anderen Ergebnissen führen.
Tilo - Mo 28.04.08 13:42
Vielleicht hilft die Funktion appendstr()?
alzaimar - Mo 28.04.08 13:45
Nee, nee. Es ging ihm um das scheinbare Paradoxon, das ein und die selbe Funktion immer länger braucht. Aber das hat sich jetzt wohl geklärt, denn es ist gar nicht ein und die selbe Funktion ;-)
WeBsPaCe - Mo 28.04.08 14:57
Tach. :-)
alzaimar hat folgendes geschrieben: |
| Nee, nee. Es ging ihm um das scheinbare Paradoxon, das ein und die selbe Funktion immer länger braucht. Aber das hat sich jetzt wohl geklärt, denn es ist gar nicht ein und die selbe Funktion ;-) |
Nicht so ganz: ich würde mal folgende Unterscheidung machen:
Weg 1: Ich habe einen Korb mit Äpfeln, nehme die Äpfel heraus, lege einen mehr dazu und werf wieder alles in den Korb rein
Weg 2: Ich habe einen Korb mit Äpfeln und werfe den zusätzlichen Apfel einfach gleich dazu
Das Ergebnis ist dasselbe, bloß dauert Weg 1 deutlich länger als Weg 2. Delphi nimmt anscheinend Weg 1, wenn ich
ws := ws + 'foo'; schreibe. Sinnvoller, da zeitsparender, ist allerdings Weg 2, also: wie setze ich Weg 2 in Delphi um?
Tilo hat folgendes geschrieben: |
| Vielleicht hilft die Funktion appendstr()? |
Funktioniert bei mir mit
WideStrings nicht. Mach ich was falsch?
MfG,
WeBBy
Delete - Mo 28.04.08 15:19
Definiere eine Zielvariable und lege deren Größe mit SetLength auf die Größe des resultierenden Strings fest.
WeBsPaCe - Mo 28.04.08 15:24
Tach.
Luckie hat folgendes geschrieben: |
| Definiere eine Zielvariable und lege deren Größe mit SetLength auf die Größe des resultierenden Strings fest. |
Du meinst von vorneherein, oder? Also bevor überhaupt irgendwas gespeichert wurde? Problem: Da weiß ich leider noch nicht, wie groß das Teil am Ende wird.
Ansonsten versteh ich nicht, was du meinst. ;)
MfG,
WeBBy
Lannes - Mo 28.04.08 15:48
Hallo,
Du weist aber zwischendurch wie groß es wird.
Um bei Deinem Beispiel zu bleiben, vergößer den Korb so, das der Apfel reinpasst.
Denke
Luckie meint es in etwa so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| var wsErg, ws : WideString; x, z, zz, i : Integer; dt : TDateTime; begin wsErg := ''; ws := 'foo'; x := 500; i := 1; while True do begin dt := NOW; Setlength(wsErg,(x * Length(ws)) + Length(wsErg)); for z := 1 to x do for zz := 1 to Length(ws) do begin wsErg[i] := ws[zz]; inc(i); end; WriteLn(FormatDateTime('SS.ZZZ', NOW - dt)); end; end. |
hazard999 - Mo 28.04.08 16:34
TStringList nehmen.
verwendet andere Speicherverwaltung als die Compiler-Magic von string-concat.
Habe das selbe Problem auch schon gehabt. Verursacht zusätzlich eine fürchterliche Speicherfragmentierung.
r u
René
WeBsPaCe - Mo 28.04.08 21:09
Okay, vielen Dank für die Antworten. ;-)
MfG,
WeBBy
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!