AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zeitoptimierung bei Stringzusammensetzung
Thema durchsuchen
Ansicht
Themen-Optionen

Zeitoptimierung bei Stringzusammensetzung

Ein Thema von amigage · begonnen am 11. Nov 2005 · letzter Beitrag vom 13. Nov 2005
Antwort Antwort
Seite 1 von 2  1 2      
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
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 11. Nov 2005, 16:19
Wofür diesen Aufwand?

Delphi-Referenz durchsuchenIntToHex
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 11. Nov 2005, 16:24
das ganze liegt daran das die länge des Strings ständig verändert wird und somit immer wieder speicher dafür angefordert wird. Schneller ist es einmal mit "SetLength" die Länge des Strings zu setzen und dann mit move den Hex-Wert an die entsprechende Stelle im speicher(String) kopieren.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
amigage

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

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 11. Nov 2005, 16:34
Wow,

erst einmal besten Dank für die schnelle Antwort.

@DGL-luke: Naja, war knapp am eigentlichen Problem vorbei

@SirThornberry:
Dein Tipp hat es gebracht!
Damit konnte ich die 3.000.000er Schleife auf 1.8 Sekunden drücken, ohne den Stirng aufteilen zu müssen.

Besten Dank. Weiter so. Werde öfter mal hier vorbeischauen. Hier kann man noch etwas lernen
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#5

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 11. Nov 2005, 17:11
dürfte denn sie allgemeinheit noch erfahren wie es gemacht wurde?
liege ich mit folgender Vermutung richtig?
Delphi-Quellcode:
j := 3;
st := 'AB';
SetLength(St2,300000);
for i := 1 to Length(St2) do
begin
   if st[1] in ['0'..'9', 'A'..'F'] then
   begin
     St2[i]:=Char(StrToInt('$' + st[1] + st[2]));
     inc(j, 1);
   end;
end;
  Mit Zitat antworten Zitat
amigage

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

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 12. Nov 2005, 08:28
Natürlich darf die Allgemeinheit das erfahren

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j : integer;
  st, sx: String;
  c, n1, n2 : TLargeInteger;
begin
QueryPerformanceFrequency(c);
QueryPerformanceCounter(n1);
 st := 'AB';
 sx := '';
 st2 := '';
 SetLength(st2, 3000000); // neu
 for i := 1 to 3000000 do
 begin
   if st[1] in ['0'..'9', 'A'..'F'] then
   begin
     sx := Char(StrToInt('$' + st[1] + st[2])); // neu
     move(sx[1], st2[i], Length(sx)+1); // neu
   end;
 end;
 SetLength(st2, Length(PChar(st2))); // etwaige NULL Strings abschneiden

QueryPerformanceCounter(n2);
Showmessage(format('Zeit: %g', [(n2 - n1)/c]));
Showmessage(IntToStr(Length(st2)));
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 12. Nov 2005, 08:50
Oh Gott, mach das Move weg!

Alt:
Delphi-Quellcode:
   begin
     sx := Char(StrToInt('$' + st[1] + st[2])); // neu
     move(sx[1], st2[i], Length(sx)+1); // neu
   end;
Neu:
Delphi-Quellcode:
   begin
     st2[i] := Chr(StrToInt('$' + st[1] + st[2]));
   end;
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
amigage

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

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 12. Nov 2005, 09:11
Mensch, dass wird ja immer besser

Die Routine braucht nun statt der anfänglichen 22 Sekunden über 1.8 Sekunden nur noch 1.1 Sekunden!!!

Gibt es hier im Forum eigentlich einen Thread mit zeitkritischen Optimierungen, wo noch mehr solche Kniffe zu finden sind?
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#9

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 12. Nov 2005, 09:23
So, jetzt noch:
Delphi-Quellcode:
j := Ord (st[1]); if j>57 then dec (j, 65) else dec(j,48);
k := Ord (st[2]); if j>57 then dec (k, 65) else dec(k,48);
st2[i] := Char (j shl 4 or k);
anstatt
st2[i] := Char(StrToInt('$' + st[1] + st[2])); und dann wird das auch was (Bei mir von 1.39 auf 0.18 Sekunden)
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
amigage

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

Re: Zeitoptimierung bei Stringzusammensetzung

  Alt 13. Nov 2005, 10:15
Megamäßig! Ich verstehe das mit dem shl (links shiften) zwar nicht wirklich

Aber es bringt bei mir Zeiten zwischen 0.055 und 0.062!
Und wenn man jetzt
Delphi-Quellcode:
j := Ord (st[1]); if j>57 then dec (j, 65) else dec(j,48);
k := Ord (st[2]); if j>57 then dec (k, 65) else dec(k,48);
lieber
Delphi-Quellcode:
      
j := Ord (st[1]); if j>57 then j := j-65 else j:=j-48;
k := Ord (st[2]); if k>57 then k := k-65 else k:=k-48;
schreibt, komme ich auf Zeiten zwischen 0.038 und 0.042!
Dec und Inc scheinen langsamer zu sein als die herkömmlich Art zu Addieren/Subtrahieren.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:39 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