27 Stimmen

Delphi StringBuilder

Gibt es in Delphi etwas Ähnliches wie den Java oder C# StringBuilder? Oder braucht Delphi keinen StringBuilder und s := s + 'einige Zeichenkette'; ist ein guter Ausdruck (hauptsächlich in for- und while-Schleifen).

1 Stimmen

Du findest möglicherweise diese Serie von Blog-Einträgen interessant.

1 Stimmen

Sie möchten TStringBuilder nicht verwenden. Es ist sehr langsam.

49voto

ulrichb Punkte 18914

Ja, Delphi bietet TStringBuilder an (seit Version 2009):

procedure TestStringBuilder;
var
  I: Integer;
  StringBuilder: TStringBuilder;
begin                StringBuilder := TStringBuilder.Create;
  try
    for I := 1 to 10 do
    begin
      StringBuilder.Append('a string ');
      StringBuilder.Append(66); // add an integer
      StringBuilder.Append(sLineBreak); // neue Zeile hinzufügen
    end;

    OutputWriteLine('Länge des endgültigen String-Builders: ' +
                    IntToStr(StringBuilder.Length));
  finally
    StringBuilder.Free;
  end;
end;

Und ja, du hast recht. s := s + 'text'; ist wirklich nicht langsamer als die Verwendung von TStringBuilder.

6 Stimmen

StringBuilder ist eigentlich nicht so effizient: delphitools.info/2013/10/30/efficient-string-building-in-del‌​phi

8voto

gabr Punkte 26255

In älteren Delphis kannst du Hallvard Vassbotn's HVStringBuilder verwenden. Ich habe es nicht geschafft, die Quellen auf seinem Blog zu finden, aber du kannst sie im OmniThreadLibrary source tree zum Beispiel abrufen (du benötigst die Dateien HVStringBuilder.pas und HVStringData.pas).

0 Stimmen

HVStringBuilder für alte Delphi-Apps zu haben ist eine gute Sache! Vielen Dank für diese Antwort.

0 Stimmen

Bevor du den Quellcode für HVStringBuilder erhältst, kannst du uns sagen, ob diese Bibliothek schneller ist als s:= s+ x ? Vielen Dank.

6voto

skamradt Punkte 15128

Delphi benötigt keine "ERFORDERLICHEN" String-Builder-Klasse, aber eine wird für Delphi 2009 bereitgestellt, wenn Sie diese verwenden möchten. Ihr Beispiel s := s + 'some string'; ist eine typische Methode zum Verketten von Zeichenfolgen und wird seit einigen Jahrzehnten in Pascal/Delphi ohne signifikante Probleme verwendet.

1 Stimmen

Das mag richtig sein, wenn alles, was du jemals tust, darin besteht, mit ein paar Zehnzeichen in einem String zu arbeiten. Aber für die Erstellung eines komplexen langen Strings mit Speicherzugriffsmustern, die verhindern, dass er vor Ort neu allokiert wird, trifft das nicht zu. Außerdem scheint deine Delphi-Zeitleiste ein wenig falsch zu sein - Jahrzehnte??? 13 Jahre seit D2...

0 Stimmen

@mghie Habe auch Pascal erwähnt, in dem ich seit Ende der 80er Jahre programmiere.

2 Stimmen

Mghie: irgendwelche Beispiele? Afaik nativer stringbuilder reserviert nur etwas mehr zusätzlichen Speicher als normal (normale Zeichenfolgen haben nur zusätzliche Kapazität aufgrund der Speicherzuordnungsgranularität). Ich frage mich, ob tstringbuilder überhaupt schneller ist, bis Ihre Zeichenfolgen länger als tausend Zeichen sind. Ich finde sehr wenig Benchmark-Informationen zu diesem Thema.

5voto

Anon Punkte 51

Der erwähnte TStringBuilder ist der richtige Weg. In Ihrem spezifischen Fall kann die Verkettung in Ordnung sein, aber ich würde trotzdem immer die Alternative ausprobieren.

Ich erstelle eine EPUB-Body-Inhalt-XHTML-Datei im Speicher (Delphi XE) und es hat so lange gedauert, um sie zu erstellen, dass ich sie nie zu Ende habe laufen lassen (ungefähr 5 Minuten plus, bevor ich aufgegeben habe). Dies ist ein Beispiel aus dem echten Leben, das etwa 800.000 Zeichen Text kombiniert. Indem ich den EXAKT gleichen Code nehme und die s:=s+'' -Style-Anweisungen direkt durch TStringBuilder.Append -Anweisungen ersetze, konnte ich die Zeit auf ungefähr 3 Sekunden reduzieren. Um es noch einmal zu betonen: Es gab keine logischen Änderungen, außer einem Wechsel von der Verkettung.

3 Stimmen

Interessant, ich würde wirklich gerne einen Testfallanbieter dafür sehen.

5voto

Todd Grigsby Punkte 745

Ich bin wirklich überrascht, dass in keinem der Kommentare oder Beispiele erwähnt wurde, dass Sie TStringBuilder anweisen können, einen Puffer entsprechend der Aufgabe während der Instantiierung vorab zuzuweisen. Mit anderen Worten, wenn Sie eine einfache Schätzung darüber abgeben können, wie viel Speicherplatz Sie wahrscheinlich benötigen werden, fügen Sie das etwas hinzu und verwenden Sie diesen Wert, um TStringBuilder zu instantiieren, um die Speicherreallokationen zu vermeiden, die die einfache Zeichenkettenverkettung stark verlangsamen:

buff := TStringBuilder.Create( tmpEstimatedSize );

Ich verwende TStringBuilder regelmäßig in neuem Code und zur Optimierung von altem Code, und die CPU-Einsparungen beim schrittweisen Aufbau großer Zeichenketten sind dramatisch. Um transparent zu sein, wenn ich nur eine Handvoll Zeichenketten verketten muss, beschäftige ich mich nicht mit TStringBuilder. Aber wenn ich beispielsweise Daten serialisiere, die potenziell eine große Datenmenge sein könnten, ist TStringBuilder die offensichtliche Lösung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X