Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
Delphi 12 Athens
|
AW: Alternative zu PosEx
29. Nov 2024, 11:11
Ich habe den Faktor bei "SetLength(Result, Count * 2)" auf 2 geändert. Das bringt noch ein par Millisekunden.
Delphi-Quellcode:
function MyStrPosEx(const SearchFor, SearchIn: string): TIntegerDynArray;
function Search(var Index: Integer): Boolean;
begin
Index := Pos(SearchFor, SearchIn, Index + 1);
Result := (Index > 0);
end;
begin
var Count: Integer := 0;
var Index: Integer := 0;
while Search(Index) do
begin
Inc(Count);
{Array vergrößern braucht viel Zeit, deshalb gleich etwas mehr Platz reservieren}
if Length(Result) < Count then
SetLength(Result, Count * 2);
Result[Count - 1] := Index;
end;
SetLength(Result, Count);
end;
Trotzdem ist natürlich jedes "SetLength()" potentiell mit dem Umkopieren des Inhalts verbunden und benötigt Zeit.
Wenn man die Menge der Ergebnisse abschätzen kann, ist es sinnvoll das Array gleich in der entsprechenden Größe zu reservieren und zum Schluss zu kürzen.
Code:
sRandomString := RandomString(8000000)
0:00:00.402
SetLength(Positions, 10000000)
StrPosEx('7', 'sRandomString', Positions)
0:00:00.102
Result = 7999774
Positions = [15,19,45,63,98,113,122,127,132,133, ... ,0,0,0,0,0,0,0,0,0,0]
Result := MyStrPosEx('7', 'sRandomString')
0:00:00.217
Length = 7999774
Result = [15,19,45,63,98,113,122,127,132,133, ... ,79999929,79999936,79999958,79999963,79999969,79999970,79999975,79999976,79999990,79999995]
Die Unterschiede im Ergebnis liegen hier daran, dass "777" bei mir zwei Fundstellen bedeuten:
Code:
sRandomString := RandomString(8000000)
0:00:00.407
SetLength(Positions, 1000000)
StrPosEx('77', 'sRandomString', Positions)
0:00:00.091
Result = 727065
Positions = [322,351,413,526,563,800,807,828,854,1113, ... ,0,0,0,0,0,0,0,0,0,0]
Result := MyStrPosEx('77', 'sRandomString')
0:00:00.108
Length = 799271
Result = [322,351,352,413,526,563,800,807,828,854, ... ,79999371,79999406,79999515,79999730,79999819,79999827,79999843,79999868,79999931,79999954]
|