スペースで区切られた文字列内の部分文字列をカウントする関数がいくつかあります。
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils,windows;
//s=string to search in
//t=string to search for
//cs=delimiters
function f0(const s,t:string;const cs:tsyscharset):integer;
var
p,q:pchar;
u:string;
begin
result:=0;
p:=pointer(s);
if p<>nil then
while p^<>#0 do
begin
while (p^<>#0) and charinset(p^,cs) do inc(p);
q:=p;
while (p^<>#0) and not charinset(p^,cs) do inc(p);
if p>q then
begin
setstring(u,q,p-q);
//writeln('[',u,']');
if u=t then inc(result);
end;
end;
end;
function f1(const s,t:string;const cs:tsyscharset):integer;
var
i,j,l:integer;
u:string;
begin
result:=0;
l:=length(s);
i:=1;
while i<=l do
begin
while (i<=l) and charinset(s[i],cs) do inc(i);
j:=i;
while (i<=l) and not charinset(s[i],cs) do inc(i);
if i>j then
begin
u:=copy(s,j,i-j);
//writeln('[',u,']');
if u=t then inc(result);
end;
end;
end;
function f2(const s,t:string;const cs:tsyscharset):integer;
var
i,j,l:integer;
u:string;
begin
result:=0;
l:=length(s);
i:=1;
while i<=l do
begin
while (i<=l) and charinset(s[i],cs) do inc(i);
j:=i;
while (i<=l) and not charinset(s[i],cs) do inc(i);
if i>j then
begin
setlength(u,i-j);
move(s[j],pointer(u)^,(i-j)*2);
//writeln('[',u,']');
if u=t then inc(result);
end;
end;
end;
type
tfunc=function(const s,t:string;const cs:tsyscharset):integer;
const
s=' de foo de'+#13+' baz blah de de blah'+#10+' asd de qwe rtz un f'+#9+' t de ds w de ';
t='de';
cs=[' ',#13,#10,#9];//CR,LF,TAB
n=5000000;
procedure time(i:integer;f:tfunc);
var
j,k:integer;
start,finish,freq:int64;
begin
QueryPerformanceCounter(start);
for j := 1 to n do k:=f(s,t,cs);
QueryPerformanceCounter(finish);
QueryPerformanceFrequency(freq);
Writeln(Format('f%u:%u:%.3fs',[i,k,(finish-start)/freq]));
end;
const
funcs:array[0..2] of tfunc=(f0,f1,f2);
var
i:integer;
begin
setpriorityclass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
for i := low(funcs) to high(funcs) do time(i,funcs[i]);
readln
end.
速度結果は、
f0:7:7,624s
f1:7:8,066s
f2:7:6,454s
私の最初の質問は、なぜ f2 は f0 より速いのですか?
2 番目の質問は、これをさらに最適化する方法を知っていますか (インライン アセンブラーなしで)。
IDE: Delphi XE2 (Unicode)