![]() |
Frage zum Aneinanderhängen von Strings
Hallo,
Die Stringkonkatenation ist ja denke ich mal nicht gerade das schnellste. Vor allem wenn ich einen ganzen Text z.B. Char für Char aneinanderhänge muss jedesmal Speicher für 1 weiteren Char angefordert werden... Wenn ich jetzt die Länge eines Strings mit SetLength auf sagen wir 200 stelle und somit auch schon mal dementsprechend viel Speicherplatz auf einen Rutsch anfordere und dann wieder schreibe S := S + 'A'; (z.B.).. Wird dann wieder Speicher angefordert oder geht das dann performanter weil noch genug verfügbar ist? Also konkret:
Delphi-Quellcode:
:arrow: Welche der beiden Schleifen ist schneller?
var Str1, Str2: String;
begin // Str1 Str1 := ''; for i:= 1 to 100000 do Str1 := Str1 + 'A'; // Str2 SetLength(Str2,100000); FillChar(Str2[1],100000,0); for i:= 1 to 100000 do Str2 := Str2 + 'A'; Gruß Neutral General |
Re: Frage zum Aneinanderhängen von Strings
Die Schleifen dürften gleichschnell sein, denn bei der zweiten wird auch immer Zeichen für Zeichen angefügt, nur dass der zweite String anschliessend 200000 Zeichen lang ist.
Schneller geht es, wenn Du die Zeichen in den jeweiligen Index schreibst:
Delphi-Quellcode:
SetLength(Str2,100000);
for i:= 1 to 100000 do Str2[i] := 'A'; |
Re: Frage zum Aneinanderhängen von Strings
Oh.. richtig.. jetzt wo du's sagst :stupid:
Jo danke ;) Ich denke dann hätte sich das auch erledigt :mrgreen: |
Re: Frage zum Aneinanderhängen von Strings
Vielleicht wäre es an der Stelle auch noch interessant zu wissen, was denn in einem String steht, wenn ich SetLength auf ihn anwende, also sowas hier
Delphi-Quellcode:
var
str : String; begin SetLength(set, 100); // <- was hat str nun für einen Wert? end; |
Re: Frage zum Aneinanderhängen von Strings
Da SetLength den Speicher nicht initialisiert, sind alle neuen Zeichen undefiniert.
Wurde zufällig ein ein neuer/leerer Speicherbereich verwendet, dann stehen #0-en drin, ansonsten halt irgendwelche zufällig dort im Speicher rumliegende Byte-/Zeichenfolgen. |
Re: Frage zum Aneinanderhängen von Strings
Ausprobieren? F1 drücken?
Und folgende Stringkonkatenation ist noch schneller:
Delphi-Quellcode:
:stupid:
C := Str1 + Str2;
Das ist ca. 10x schneller als die Variante, die erst per SetLength den gesammten Speicher reserviert, welche widerum 10x schneller als die Variante ist, die den String Zeichen für Zeichen zusammenbappt. Ich habe das übrigens einfach ausprobiert, das hat mich 5 min gekostet und die Frage war beantwortet. Zitat:
Das hätte man übrigens auch durch Verwendung des magischen EffEins ermitteln können. |
Re: Frage zum Aneinanderhängen von Strings
Zitat:
Delphi-Quellcode:
Denn sonst ist die 2 noch langsamer, da sie schon mit einem größerem Ausgangsstring genau das Selbe (in Bezug auf die Schleife) macht.
// Str2
SetLength(Str2, 100000); //FillChar(Str2[1], 100000 * SizeOf(Char), 0); for i := 1 to 100000 do Str2[i] := 'A';
Delphi-Quellcode:
Dank 'ner guten Codeoptimierung seitens des Delphicompilers ist dieses mit das Schnellste.
Var P: PChar;
// Str2 SetLength(Str2, 100000); P := @Str[1]; for i := 99999 downto 0 do P[i] := 'A'; Schneller ist da nur noch dieses (vorallem seit D2006?, wo das FastCodeProjekt in Delphi integriert wurde)
Delphi-Quellcode:
oder gleich
// Str2 = AnsiString
SetLength(Str2, 100000); FillChar(@Str2[1], 100000, 'A'); ![]()
Delphi-Quellcode:
Str2 := StringOfChar('A', 100000);
Dieses
Delphi-Quellcode:
enspricht ja
Str1 := '';
for i:= 1 to 100000 do Str1 := Str1 + 'A';
Code:
Str1 leeren (falls noch nicht leer)
Schleife mit 100.000 Durchgängen neuen String mit Länge ( Length(Str1) + Length('A') ) reservieren beide Strings in den neuen String reinkopieren alten String Str1 freigeben Variable Str1 durch neuen String ersetzen. Ende der Schleife |
Re: Frage zum Aneinanderhängen von Strings
Hallo,
Vielleicht hätte ich erwähnen sollen, dass es um das Scannen von Quellcode geht. Und da muss ich eben nunmal Zeichen für Zeichen durch den String geben und wenn ich auf einen String treffe muss ich dann auch immer Zeichen für Zeichen schauen ob das nächste Zeichen noch zu dem String gehört und ggf. zum Token hinzufügen. Von daher nutzt mir
Delphi-Quellcode:
o.ä. nichts :mrgreen:
FillChar(Str,10000,'A');
|
Re: Frage zum Aneinanderhängen von Strings
Besser als
Delphi-Quellcode:
ist dann halt
S := S + irgendwas;
Delphi-Quellcode:
Denn wenn Insert, bzw. der Speichermanager den internen Speicher hier "inplace", also ohne verschieben/umkopieren vergrößern kann, dann wird nur noch der anzuhängende String da reinkopiert und fertig.
//Insert(irgendwas, S, Length(S) + 1);
Insert(irgendwas, S, MaxInt); Zitat:
|
Re: Frage zum Aneinanderhängen von Strings
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz