![]() |
Quicksort Algo für Strings optimieren
Hallo,
Ich wollte mal fragen, ob man folgenden Quicksort Algo für Strings optimieren kann. (Angenommen es ist ein sehr großes Array)
Delphi-Quellcode:
das Tauschen der Variablen kann man doch bestimmt irgendwie optimieren, evtl. mit CopyMemory oder irgendwelchen anderen Pointer/Asm Operationen :?:
procedure QuickSort(var Strings: TStringArray; Start, Stop: Integer);
var Left: Integer; Right: Integer; Mid: Integer; Pivot: string; Temp: string; begin Left := Start; Right := Stop; Mid := (Start + Stop) div 2; Pivot := Strings[mid]; repeat while Strings[Left] < Pivot do Inc(Left); while Pivot < Strings[Right] do Dec(Right); if Left <= Right then begin Temp := Strings[Left]; Strings[Left] := Strings[Right]; // Swops the two Strings Strings[Right] := Temp; Inc(Left); Dec(Right); end; until Left > Right; if Start < Right then QuickSort(Strings, Start, Right); // Uses if Left < Stop then QuickSort(Strings, Left, Stop); // Recursion end; Danke :!: |
Re: Quicksort Algo für Strings optimieren
Hast Du denn gemessen ob dies wirklich der Flaschenhals ist in diesem Quicksort?
|
Re: Quicksort Algo für Strings optimieren
Zitat:
Bei mir braucht es atm für 1.000.000 Strings 1800 ms. |
Re: Quicksort Algo für Strings optimieren
[quote="kcx"]
Zitat:
Code:
// Div 2
mov edx, eax sar edx,1 jns +$03 adc edx,$00
Code:
Das hat jetzt zwar nix mit den Strings zu tun, aber wird bei Dir immerhin in der Rekursion oft aufgerufen. Und wo wir bei dieser sind, zwei Rekursionen sind bei dem Algorhytmus überflüssig, es reicht der erste, den zweiten stellt man durch ein verschachteltes repeat dar, das ist gesünder für den Stack!.
// Shr 1
mov ecx,eax shr ecx,1 |
Re: Quicksort Algo für Strings optimieren
Du kannst ca. 10% sparen, indem Du die Rekursion rausnimmst.
Dazu implementierst du einen Stack, der die (L,R) Tupel verwaltet. Statt des rekursiven Aufrufes, schiebst du die untere und obere Grenze auf den Stack. Der Stack wird so lange abgearbeitet, bis er leer ist. Dann kann es sein, das z.B. Insertionsort bei kleinen Abschnitten schneller ist. Alles in Allem könntest Du so imho max. 15% einsparen. @Union: Ich wäre jede Wette eingegangen, das der Compiler das 'DIV 2' selber in 'SHR 1' optimiert. Bringt hier aber max 10ms. |
Re: Quicksort Algo für Strings optimieren
Zitat:
Code:
Also fast 25% schneller nur durch Änderung in shr.Aufrufe Dauer Gesamt Original 77,163 1.257 μs 96.986 ms Shr 1 77,163 0.958 μs 73.909 ms |
Re: Quicksort Algo für Strings optimieren
Ich auch, bei mir waren's 50% (SHR war doppelt so schnell).
edit: Das Quicksort oder eine einfache Testschleife? Ich hab 1 Mio mal DIV mit SHR verglichen und da war ein kaum messbarer Unterschied. aber bei 100.000.000 Aufrufen schon. edit2: Ich habe keinen Unterschied im Quicksort (bei 1Mio Strings) feststellen können. |
Re: Quicksort Algo für Strings optimieren
Nein, ich habe nur das Quicksort gemessen. Testschleife (LoadFromFile aus einer Textdatei, füllen des Arrays) ist nicht mitgemessen. Ich mache immer 3 gleiche Aufrufe mit den selben Daten (~25000 Strings).
Hier die Ergebisse wenn man die zweite rekursive Zeile entfernt und durch ein repeat ersetzt. Die Funktion ist wieder langsamer, wird dafür aber weniger durch sich selbst aufgerufen!
Code:
Original 77,163 0.969 us 74.756 ms
Shr 1 77,163 0.883 us 68.138 ms repeat 49,152 1.287 us 63.280 ms |
Re: Quicksort Algo für Strings optimieren
Und hier das überarbeitete durch kcx von Derek van Daal entwendete Meisterwerk...
Delphi-Quellcode:
Neue Messreihe:
procedure QuickSort(var Strings: TStringArray; Start, Stop: Integer);
var Left: Integer; Right: Integer; Mid: Integer; Pivot: string; // Temp: string; PTemp : integer; begin // Dieses repeat... repeat Left := Start; Right := Stop; // Mid := (Start + Stop) div 2; Mid := (Start + Stop) shr 1; Pivot := Strings[mid]; repeat while Strings[Left] < Pivot do Inc(Left); while Pivot < Strings[Right] do Dec(Right); if Left <= Right then begin // So wars vorher... // Temp := Strings[Left]; // Strings[Left] := Strings[Right]; // Swops the two Strings // Strings[Right] := Temp; // Es stürzt nicht ab, aber ist das auch richtig? Na wenigstens 30x so schnell... PTemp := integer(Strings[Left]); integer(Strings[Left]) := integer(Strings[Right]); integer(Strings[Right]) := PTemp; Inc(Left); Dec(Right); end; until Left > Right; if Start < Right then QuickSort(Strings, Start, Right); // Uses Recursion Start := Left; // ... mit diesem Until verringert die Anzahl der Rekursiven Aufrufe. Aufrufe = Stack + Parameter + Push+Pop -> BÖSE until Left >= Stop; end;
Code:
Original 77,163 0.969 us 74.756 ms
Shr 1 77,163 0.883 us 68.138 ms repeat 49,152 1.287 us 63.280 ms Swap int 49,152 0.787 us 38,663 ms Swap Original 77,163 0.393 us 30.356 ms Swap Integer 77,163 0,015 us 1.133 ms |
Re: Quicksort Algo für Strings optimieren
Hallo,
Zitat:
Gruß Hawkeye |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:22 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