![]() |
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:
Es geht darum durch diesen Algo knapp 13 Millionen Zeilen zu jagen ;)
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; 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 :) |
Re: Code Optimierung
Zieh das SetLength vor die Schleife. Das bewirkt Wunder.
|
Re: Code Optimierung
Setzte die Größe des dynamischen Arrays vor der Schleife einmalig.
|
Re: Code Optimierung
Ich weiß aber nicht wie groß das Array wird... :(
|
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?
|
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. |
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?)) |
Re: Code Optimierung
Zitat:
Lieber einmal größer initialisieren und am Ende kürzen |
Re: Code Optimierung
Zitat:
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:
|
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 18:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz