Einzelnen Beitrag anzeigen

amigage

Registriert seit: 11. Nov 2005
Ort: Leipzig
270 Beiträge
 
Delphi 11 Alexandria
 
#1

Zeitoptimierung bei Stringzusammensetzung

  Alt 11. Nov 2005, 16:15
Hallo liebe Delphi-Gemeinde,

ich bin ganz neu im Forum.
Grund dafür ist ein Test, den ich durchgeführt habe und zu einer erschreckenden Erkenntnis kam.

Es geht um die Umwandlung von Hex-Zahlen in Strings;

Der vereinfachte Code:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j : integer;
  st, st2, st3 : String;
  c, n1, n2 : TLargeInteger;
begin
 QueryPerformanceFrequency(c);
 QueryPerformanceCounter(n1);

 j := 3;
 st := 'AB';
 st2 := '';
 for i := 1 to 300000 do
 begin
   if st[1] in ['0'..'9', 'A'..'F'] then
   begin
     St2 := St2 + Char(StrToInt('$' + st[1] + st[2]));
     inc(j, 1);
   end;
 end;

 QueryPerformanceCounter(n2);
 Showmessage(format('Zeit: %g', [(n2 - n1)/c]));
end;
In einer 300.000er Schleife wird immer wieder aus den Werten AB der HexCode gebildet und in ein Char umgewandelt.
Die benötigte Zeit war bei mir 0.3 Sekunden.

Erhöhe ich die Schleife um den Faktor 10 erhöht sich aber meine Zeit um das 70 fache, auf 21 Sekunden!!!
Es scheint irgendwie am String zu liegen. Je größer er wird, umso langsamer wird die Zusammensetzung.

Also kam mir die Idee, den String st2 nach 100.000 Durchgängen an einen neuen zu übergeben und dann zu leeren.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j : integer;
  st, st2, st3 : String;
  c, n1, n2 : TLargeInteger;
begin
 QueryPerformanceFrequency(c);
 QueryPerformanceCounter(n1);
 j := 3;
 st := 'AB';
 st2 := '';
 st3 := '';
 for i := 1 to 3000000 do
 begin
   if st[1] in ['0'..'9', 'A'..'F'] then
   begin
     St2 := St2 + Char(StrToInt('$' + st[1] + st[2]));
     inc(j, 1);
   end;
   if Length(St2) > 100000 then
   begin
     St3 := St3 +St2;
     St2 := '';
   end;
 end;
 St3 := St3 +St2;

 QueryPerformanceCounter(n2);
 Showmessage(format('Zeit: %g', [(n2 - n1)/c]));
end;
Schwupps, und es waren nur noch 8 Sekunden, statt 21 !!!
Gibt es eine bessere, elegantere Lösung?

Am Ende benötige ich jedoch eine Ausgabe im Stringformnat.

Besten Dank schon im voraus, für jeden Hinweis.
  Mit Zitat antworten Zitat