olesio napisał(a)
Chętnie zobaczę szybszą wersję. Sam kiedyś coś tam próbowałem przerobić. Ale po zbyt dużej ilości zmian kod nie działał jak chciałem, więc odpuściłem by nie skopać całości.
Przede wszystkim zwróć uwagę, że w funkcji FindStringInMemory
ta pętla:
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
if IgnoreCase then
begin
S1 := AnsiLowerCase(Chr(Buffer[X + Y]));
S2 := AnsiLowerCase(Chr(ArrayOfBytes[Y]));
if S1 <> S2 then
begin
Found := False;
Break;
end;
end
else
begin
if Buffer[X + Y] <> ArrayOfBytes[Y] then
begin
Found := False;
Break;
end;
end;
end;
sprawdza IgnoreCase
w każdej iteracji; A że warunek sprawdzany jest dla każdej pary znaków, to pętla jest baaardzo wolna; Lepszym rozwiązaniem będzie albo sprawdzenie IgnoreCase
raz i zapisanie dwóch osobnych pętli:
if IgnoreCase then
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
Found := AnsiLowerCase(Chr(Buffer[X + Y])) = AnsiLowerCase(Chr(ArrayOfBytes[Y]));
if not Found then Break;
end
else
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
Found := Buffer[X + Y] = ArrayOfBytes[Y];
if not Found then Break;
end;
albo wydzielenie tych pętli do osobnych funkcji, oraz użycie dodatkowej zmiennej z adresem na właściwą funkcję szukającą; Wtedy warunek będzie spełniany jedynie raz w skali całej FindStringInMemory
(na początku, aby pobrać pointer na właściwą funkcję), a nie w skali pętli While (powyższy kod sprawdza warunek raz na jedną iterację pętli While, co jest i tak redundantne);
Dodatkowo, jeśli chodzi o tę drugą pętlę w sugerowanym kodzie, czyli:
else
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
Found := Buffer[X + Y] = ArrayOfBytes[Y];
if not Found then Break;
end;
można ją zamienić na super-szybką CompareMem, co przełoży się na większą efektywność w przypadku, gdy argument IgnoreCase
posiada stan False:
if IgnoreCase then
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
Found := AnsiLowerCase(Chr(Buffer[X + Y])) = AnsiLowerCase(Chr(ArrayOfBytes[Y]));
if not Found then Break;
end
else
Found := CompareMem(@Buffer[X], @ArrayOfBytes[0], Length(ArrayOfBytes));
Mam nadzieję, że nic nie pomyliłem - poprawiałem w notatniku;
Zapewne da się jeszcze bardziej skrócić i przyspieszyć te dwie funkcje, jednak to nie dziś - już myślenie mam słabe; W każdym razie jeśli zależy Ci na przyspieszeniu tego kodu, to chętnie pobawię się w wolnym czasie i coś pokombinuję.