function MyStrPosEx(const SearchFor, SearchIn: string; Estimated: Integer = 0): TIntegerDynArray;
function Search(const SearchFor, SearchIn: string; varIndex: Integer): Boolean; inline; begin Index := Pos(SearchFor, SearchIn, Index + 1);
Result := (Index > 0); end;
begin
SetLength(Result, Estimated); var Count: Integer := 0; varIndex: Integer := 0; while Search(SearchFor, SearchIn, Index) do begin
Inc(Count); {Array vergrößern braucht viel Zeit, deshalb gleich etwas mehr Platz reservieren} if Estimated < Count then begin
Estimated := Count * 2;
SetLength(Result, Estimated); end;
Result[Count - 1] := Index; end;
SetLength(Result, Count); end;
Result := MyStrPosEx('7', sRandomString, 0)
0:00:00.168
Result := MyStrPosEx('7', sRandomString, 10000000)
0:00:00.157
Sorry, aber ich kann die Ergebnisse Deiner Zeitmessungen nicht nachvollziehen.
Ich habe SRandomString auf eine Länge von 80 Mio gesetzt und mit Zufallszeichen im Bereich "0".."9" gefüllt.
In Deiner Funktion "Search" habe ich "Pos" durch "PosEx" (aus System.StrUtils) ersetzt, weil bei mir (Delphi XE2) "Pos" keinen Offset unterstützt.
Ergebnisse im Anhang.
Meine Test-Prozedur:
Ich find das ja putzig, wenn Leute Messergebnisse auf höchstwahrscheinlich sehr unterschiedlicher Hardware und Delphi Versionen vergleichen, die mind 10 Jahre auseinander liegen.
Stefan “Simplicity, carried to the extreme, becomes elegance.” Jon Franklin
Bei mir Delphi 12.
Der Zeitunterschied verschindet bei mir praktisch, wenn statt '7' nach "77" gesucht wird.
Da in beiden Fällen der gesamte String durchsucht wird, meine Vermutung:
Die vielen Aufrufe von Pos bremsen (sind ja nicht inline).
Die Suche selbst innerhalb von Pos scheint optimal (zumindest in Delphi 12).
Eigentlich wollte ich nur die Verwendung von SetLength demonstrieren, damit man die Anzahl der Ergebnisse nicht vorher raten muss.