Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi String dynamisch erstellen??? (https://www.delphipraxis.net/148468-string-dynamisch-erstellen.html)

romber 2. Mär 2010 18:43


String dynamisch erstellen???
 
Hallo!

In diesem Thread wurde ich auf die folgende Aussage von shmia aufmerksam:

Zitat:

Zitat von shmia
Die SQL-Befehle sollte man nicht über eine Query-Komponente absenden, sondern falls möglich direkt über das Connection-Objekt oder Database-Objekt.
Beim Zusammenbauen der SQL-Befehle sollte man darauf achten, dass man nicht Folgendes tut:
Delphi-Quellcode:
SQL := SQL + ....;
Hierbei würde jedes Mal der String verlängert, was zur Folge hat, dass ein neuer Speicherblock notwendig wird und dann der alte Block auf den neuen kopiert wird.

Gilt es für die Strings allgemein oder nur im Fall mit den SQL-Befehlen? Nehmen wir an, ich habe einen String, der je nach Situation dynamisch erweitert werden soll:

Delphi-Quellcode:
if Length(StringData) <> '' then
XMLData := XMLData + StringData
Wie wird es denn sonst gemacht?

s-off 2. Mär 2010 19:36

Re: String dynamisch erstellen???
 
Welche Delphi-Version nutzt Du denn?

Ab 2009 gibt es die neue StringBuilder-Klasse, die zwar langsamer sein soll (habe ich irgendwo mal gelesen; ich glaube bei Marco Cantu), aber dafür nicht das Verhalten der regulären Stringkonkatenation geht.
Ich kenne diese Klasse nur aus C# - ob sie für Delphi genauso funktioniert, weiß ich nicht.

jfheins 2. Mär 2010 20:29

Re: String dynamisch erstellen???
 
Wenn du schon vorher weist, wie lang der String wird, kannst du das schon mit setlength festlegen - der string wird dann erst umkopiert wenn der Platz nicht mehr reicht

romber 2. Mär 2010 21:00

Re: String dynamisch erstellen???
 
Zitat:

Zitat von jfheins
Wenn du schon vorher weist, wie lang der String wird, kannst du das schon mit setlength festlegen

Und wenn ich es nicht mal ungefähr weiss, was dann? Wenn die o.b. Methode nicht ganz OK ist, dann muss es wohl eine richtige Methode geben.

Astat 2. Mär 2010 22:08

Re: String dynamisch erstellen???
 
Hallo Romberg, str1 + str2 + str3 ist unter Delphi so schnell, dass Otto Normalverbraucher sich heute, darüber
wirklich keine Gedanken mehr machen braucht.

Unter .Net, Java ist Str1 + Str2 usw. tödlich, da hier jeweils Objekte verknüpft werden, dies hat dazu geführt,
dass manche glauben , dies sei in Delphi auch so.

Für Benchmarks, ist es wichtig den String vorher eine definierte (großzügige) Länge zu geben, und dann mit
normaler Pointerarithmetic, diesen "Buffer" zu füllen. Ist dann wirklich min um Faktor 5X schneller.

lg. Astat

s.h.a.r.k 2. Mär 2010 22:26

Re: String dynamisch erstellen???
 
Zitat:

Zitat von Astat
Hallo Romberg, str1 + str2 + str3 ist unter Delphi so schnell, dass Otto Normalverbraucher sich heute, darüber
wirklich keine Gedanken mehr machen braucht.

Wobei ich auch diese Meinung vertrete. Es ist zwar schon recht nett, wenn man in Benchmarks ganz vorne liegt, aber für wahrscheinlich 99% der Anwendungen spielt das absolut keinerlei Rolle, außer man will *die* schnellste JavaScript-Engine schreiben.

Abgesehen davon sollte man aber über die Problematik von String-Konkatenation wissen.

Kleiner Hinweis aus der Hilfe: Dort wird gerate den "+"-Operator anstatt der Funktion conact() zu verwenden. Dort steht, dass + eben schneller ist :zwinker:

romber 3. Mär 2010 00:06

Re: String dynamisch erstellen???
 
Zitat:

Zitat von Astat
Für Benchmarks, ist es wichtig den String vorher eine definierte (großzügige) Länge zu geben, und dann mit
normaler Pointerarithmetic, diesen "Buffer" zu füllen. Ist dann wirklich min um Faktor 5X schneller.

Was ist diese "normale Pointerarithmetic"? Ein Beispiel wäre sehr gut.

himitsu 3. Mär 2010 06:36

Re: String dynamisch erstellen???
 
Zitat:

Zitat von romber
Was ist diese "normale Pointerarithmetic"? Ein Beispiel wäre sehr gut.

PChar/PAnsiChar/PWideChar

Wobei es ab Delphi 2009 sehr hilft, wenn man dieses schrecklich umgesetzte, wenn auch gut gemeinte, aber völlig schwachsinige StringChecking abschaltet.


Zitat:

Zitat von romber
Und wenn ich es nicht mal ungefähr weiss, was dann?

Dann mußt du es eben Messen oder es lassen?

Es kommt dann darauf an, was schneller ist:
- zwei Durchläufe > messen/zählen, Stringlänge setzen und dann kopieren
- oder eben etwas unoptimaler die Strings einzeln concatieren.

alzaimar 3. Mär 2010 06:59

Re: String dynamisch erstellen???
 
Sei X dein String, der zu füllen ist.
Delphi-Quellcode:
Var
  CurrentCharCountInX : Integer;

Procedure InitializeX;
Begin
  SetLength (X, 1024);
  CurrentCharCountInX := 0
End;

Procedure EnsureProperLengthOfX (LengthOfStringToAdd : Integer);
Begin
  If CurrentCharCountInX + LengthOfStringToAdd > Length (X) Then
    SetLength (X, 2 * Length(X));
End;

Procedure AppendStringToX (Const aString : String);
Var
  LengthOfString : Integer;

Begin
  LengthOfString := Length(aString);
  EnsureProperLengthOfX (LengthOfString);
  Move (aString[1], X[CurrentCharCountInX + 1], LengthOfString);
  Inc (CurrentCharCountInX , LengthOfString);
End;

Procedure FinalizeX;
Begin
  SetLength (X, CurrentCharCountInX);
End;

// TODO: Gib X einen besseren Namen

(*
 Aufruf:

 InitializeX;
 AppendStringToX (Str1);
 ...
 AppendStringToX (StrN);
 FinalizeX;
*)
Wesentlich besser sollte es, denke ich, nicht gehen. Vielleicht bringt das auch überhaupt nichts. :gruebel:
Natürlich kann/sollte man die generische Move-Routine durch einen Gewinner der FastCode-Challenge ersetzen. Auch ein 'Inline' sollte noch etwas bringen.

Aber im Wesen dürfte das nahe am Optimum sein. Aber wie Astat schon treffend anmerkte, braucht das im normalen Leben kein Schwein. Vor allen Dingen nicht, wenn der String anschließend als SQL-Befehl an einen SQL-Server geschickt wird. Ich vermute in diesem Fall den Performancebottleneck nämlich nicht beim Konkatenieren... :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz