Как-то так, думаю:
Код:
function arrFind(Const Arr, fArr: Array Of Byte): integer;
var i, m, n:integer;
ch, lastch: byte;
table: array[0..255] of WORD; // можно и Integer, если fArr длиннее 64кб
begin
m := Length(fArr);
n := Length(Arr);
for i := 0 to 255 do
table[i] := m;
for i := 0 to m - 2 do
table[fArr[i]] := m - i -1;
lastch := fArr[m-1];
i := 0;
while ( i <= n - m ) do
begin
ch := Arr[ i + m - 1 ];
if ( ch = lastch ) then
if ( CompareMem(@(Arr[i]), @(fArr[0]), m-1 ) ) then
begin
Result := i;
exit;
end;
i := i + table[ ch ];
end;
end;
Собственно, код взят по ссылке с вики и портирован на делфи с минимальными изменениями.
И если уж устраивать скоростную фаллометрию, то гонять надо автоматом на разных комбинациях (степень похожести и кол-во частичных вхождений, размеры разные пробовать и т.д) и собирать статистику. Попробуй на таких массивах:
Arr1:
1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6,...[и так 100 000 раз]...5,6,
7
fArr: 1,2,3,4,5,6,7
Пример, ессно, искусственный, но все же. На нем стандартный код с флагом или goto будет работать очень медленно. В реальности конечно не все так плохо, но БМХ должен быть быстрее, т.к. запускает сравнение памяти (цикл в цикле) не на каждом символе, а скачет с большими пропусками. Но на выборке блоков памяти с высокой энтропией (максимально случайных - см. данные в архиве, шифрованная информация и т.п.), думаю, разницы заметно почти не будет. Хотя зачем нужно искать что-то в высокоэнтропийном блоке, когда он по определению содержит бред...
И кстати. 100 000 - это мало. Надо хотя бы 1000000, а лучше больше. И разумеется, тест проводится множество раз подряд и замеряется общее время. Иначе разницу не увидеть, а вылезет она только тогда, когда мощный сервер будет обрабатывать тысячи таких запросов и не справится.
