Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Code Optimierung (https://www.delphipraxis.net/117590-code-optimierung.html)

Diamondback2007 21. Jul 2008 16:02


Code Optimierung
 
Hallo zusammen,

ich habe hier einen ganz kleinen Algorithmus den ich gerne noch etwas optimieren würde, da er sehr zeitkritisch ist.

Hier mal die interessanten Stellen:

Delphi-Quellcode:
while sl.Count > 0 do
      begin
        SetLength(IDArray, Length(IDArray) + 1);
        IDArray[High(IDArray)].ID := Copy(sl.Strings[0], 0, Pos(';', sl.Strings[0]) - 1);
        IDArray[High(IDArray)].Sum := IDArray[High(IDArray)].Sum + StrToInt32_JOH_IA32_7_a(ExtractPZN(sl.Strings[0]));
        sl.Delete(0);
        for i := sl.Count - 1 downto 0 do
          begin
            if IDArray[High(IDArray)].ID = ExtractID(sl.Strings[i]) then
              begin
                IDArray[High(IDArray)].Sum := IDArray[High(IDArray)].Sum + StrToInt32_JOH_IA32_7_a(ExtractPZN(sl.Strings[i]));
                sl.Delete(i);
              end;
          end;
      end;
Delphi-Quellcode:
function ExtractPZN(const Value: string): string; inline;
begin
  Result := Copy(Value, 9, 7);
{$MESSAGE Warn 'Methode geht von einer konstanten Länge der PZN aus.'}
end;

function ExtractID(const Value: string): string; inline;
begin
  Result := Copy(Value, 0, 7);
{$MESSAGE Warn 'Methode geht von einer konstanten Länge der ID aus.'}
end;
Es geht darum durch diesen Algo knapp 13 Millionen Zeilen zu jagen ;)
Momentan braucht er für 100.000 Sätze knapp 24 Sekunden.
Kann man das noch schneller machen?
Achja die seltsamen IntToStr-Methoden sind Replacements vom FastCodeprojekt und haben schon ziemlich viel gebracht :)

Apollonius 21. Jul 2008 16:04

Re: Code Optimierung
 
Zieh das SetLength vor die Schleife. Das bewirkt Wunder.

mkinzler 21. Jul 2008 16:05

Re: Code Optimierung
 
Setzte die Größe des dynamischen Arrays vor der Schleife einmalig.

Diamondback2007 21. Jul 2008 16:13

Re: Code Optimierung
 
Ich weiß aber nicht wie groß das Array wird... :(

Diamondback2007 21. Jul 2008 16:15

Re: Code Optimierung
 
Obwohl also ich könnte natürlich eine statisches Array draus machen mit ner Größe die auf jeden Fall reicht. Macht das Sinn?

Apollonius 21. Jul 2008 16:23

Re: Code Optimierung
 
Falls das Array vor der Schleife die Länge 0 hat, hat es danach höchstens so lang wie die Stringliste vor der Schleife. Also kannst du die Länge vor der Schleife auf diese obere Schranke setzen, in der Schleife dann mit einer Variablen mitzählen und nachher dann anpassen. Das sind dann nur noch zwei SetLength-Aufrufe.

Des Weiteren würde ich empfehlen, getrennte Daten getrennt zu speichern (z.B. in Records - das spart die Copy-Aufrufe) und eine Zahl auch als Zahl zu speichern.

nahpets 21. Jul 2008 16:26

Re: Code Optimierung
 
High(IDArray) wird ziemlich oft ermittelt, speicher den Wert einmal in einer Variabel und benutze diese, dürfte immer Length(IDArray) + 1 sein (?), muss dann nur einmal pro Schleifendurchlauf der äußeren Schleife ermittelt werden.

Ändert sich die Größe des Arrays während der Laufzeit?

Ist sl sortiert? Wenn ja, dann müsstest Du einen Algorhythmus finden können, der ohne sl.delete(0) auskommt.

Eventuell ist ein sl.sort und dann sequentiell abarbeiten schneller.

Kannst Du die zu erwartende Größe des Array vorher bestimmen, dann musst Du sie nur einmal setzen. (Könnte ein Nebeneffekt des Sortierens sein, dass die Ermittlung vereinfacht wird. (= Anzahl der ID's?))

mkinzler 21. Jul 2008 16:29

Re: Code Optimierung
 
Zitat:

Zitat von Diamondback2007
Ich weiß aber nicht wie groß das Array wird... :(

Maximal sl.Count

Lieber einmal größer initialisieren und am Ende kürzen

Diamondback2007 21. Jul 2008 16:40

Re: Code Optimierung
 
Zitat:

Zitat von Apollonius
Falls das Array vor der Schleife die Länge 0 hat, hat es danach höchstens so lang wie die Stringliste vor der Schleife. Also kannst du die Länge vor der Schleife auf diese obere Schranke setzen, in der Schleife dann mit einer Variablen mitzählen und nachher dann anpassen. Das sind dann nur noch zwei SetLength-Aufrufe.

Des Weiteren würde ich empfehlen, getrennte Daten getrennt zu speichern (z.B. in Records - das spart die Copy-Aufrufe) und eine Zahl auch als Zahl zu speichern.

Auf die Daten an sich habe ich leider keinen Einfluss, die muss ich nehmen wie sie kommen.
Und wo speichere ich eine zahl nicht als Zahl? eher andersherum ;) Einen string als Zahl ;)

Das Setzen von SetLength vor der Schleife hat bei 100.000 Sätzen noch nicht wirklich was gebracht, aber ich denke bei mehr sollten das was bringen.

Zitat:

Zitat von nahpets
High(IDArray) wird ziemlich oft ermittelt, speicher den Wert einmal in einer Variabel und benutze diese, dürfte immer Length(IDArray) + 1 sein (?), muss dann nur einmal pro Schleifendurchlauf der äußeren Schleife ermittelt werden.

Ändert sich die Größe des Arrays während der Laufzeit?

Ist sl sortiert? Wenn ja, dann müsstest Du einen Algorhythmus finden können, der ohne sl.delete(0) auskommt.

Eventuell ist ein sl.sort und dann sequentiell abarbeiten schneller.

Kannst Du die zu erwartende Größe des Array vorher bestimmen, dann musst Du sie nur einmal setzen. (Könnte ein Nebeneffekt des Sortierens sein, dass die Ermittlung vereinfacht wird. (= Anzahl der ID's?))

Also sl ist nicht sortiert und die Größe ändert sich eigentlich auch nicht wenn ich das vorher mache.

Apollonius 21. Jul 2008 16:44

Re: Code Optimierung
 
Natürlich speicherst du Zahlen als Strings. Deshalb brauchst du ja eine StrToInt-Funktion. ;-)
Und diese rufst du für die PZN-Strings mehrfach auf. Also ist es effektiver, wenn du aus deinem String einmal die Daten extrahierst und sie in einem Record speicherst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:33 Uhr.
Seite 1 von 3  1 23      

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