Satty67 und Himitsu: Die AnsiCompareStr / AnsiCompareText Funktionen sind ja unglaublich langsam. Ich habe mir erlaubt, dies etwas zu optimieren. Die Grundidee ist die, anhand der AnsiCompareXXX-Routinen eine 'SortOrder'-Tabelle für einzelne Zeichen zu erzeugen und die Strings Zeichen für Zeichen mit Hilfe dieser Tabelle zu vergleichen.
Dazu erstelle ich ein Array Of Char, mit A[c] = c. Danach sortiere ich dieses Array mit Hilfe der Ordnungsfunktion 'AnsiCompareStr'. Der Index des Zeichens 'C' ist also seine Ordnung. Wenn Index[C] > Index [D] (C und D sind Zeichen), dann liegt C in der Sortierreihenfolge hinter D. Logisch, irgendwie.
Nun nehme ich mir diese Indexfunktion und vergleiche mit ihrer Hilfe zwei Strings Zeichen für Zeichen. Ich vergleiche also nicht die Zeichen direkt, sondern ihren Index.
Hier die Routinen:
Delphi-Quellcode:
Var
SortOrder : Array [Char] Of Integer;
Procedure CreateSortOrder;
var
Samples: array[Char] of String;
c, d, h: Char;
begin
for c := #0 to #255 do
Samples[c] := c;
// Bubblesort the array
for c := #0 to #255 do
for d := succ(c) to #255 do
if AnsicompareStr(Samples[c], Samples[d]) > 0 then begin
h := Samples[c];
Samples[c] := Samples[d];
Samples[d] := h
end;
// Create the 'Index'-function
for c := #0 to #255 do
SortOrder[Samples[c]] := Ord(c);
end;
Und nun die Vergleichsfunktion
Delphi-Quellcode:
function FasterAnsiCompareString(const aKey1, aKey2: string): Integer;
Var
P1,p2 : PChar;
Begin
p1 := @aKey1[1];
p2 := @aKey2[1];
While (SortOrder[p1^] = SortOrder[p2^]) and (p1^<>#0) and (p2^<>#0) do Begin
inc(p1);
inc(p2);
End;
if SortOrder[p1^] = SortOrder[p2^] then
Result := 0
else if p1^ = #0 then
Result := -1
else if p2^ = #0 then
Result := 1
else Result := SortOrder[p1^]-SortOrder[p2^];
end;
Ich habe es ein wenig getestet, aber bitte prüft nochmal. Es ist 'etwas' schneller als AnsiCompareStr (bei mir: 43x
)
Das, und eine robustere Version der Skiplists sollte die Disqualifikation aufheben. Auf meinem Laptop wird die Testdatei in 2300ms so sortiert, wie Satty67 es wünscht.