Char は String よりも高速であるという理論がありましたが、試してみる必要がある場合もあります....
String の代わりに CHAR を返すことで、16 倍改善できます。文字列の割り当てに関係していると思います。
元のコードを DUnit テスト フレームワークに落とし込み、それを 1 億回ループで実行するテストを追加しました。私はそれをYNSLoop(文字列のS)と呼び、次に文字列の代わりにCharを返すYNCLoop(CharのC)と呼ばれる別のものを作成し、配列を使用したDavidのコードに基づいて別のものを作成し、それをYNALoop(配列のA)と呼びました。
次に、David の提案に従って、オリジナルのインライン バージョンを作成しました。それが良かったので、Inlined Char バージョンも作成しました。そしてねえ、Char バージョンのインライン バージョンはさらに高速です。
YNSLoop: 4487 ms (Original)
YNSILoop: 1226 ms (Original, Inlined)
YNCLoop: 266 ms (Char instead of String)
YNCILoop: 124 ms (Char Inlined)
YNALoop: 4548 ms (Array)
結論: String の代わりに Char を使用して回避できる場合は、それを実行してください。いずれにせよ、可能であればインライン化してください。
以下のコード:
function BooleanToYNSI(isTrue: Boolean): string; inline;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNS(isTrue: Boolean): string;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNC(isTrue: Boolean): Char;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNCI(isTrue: Boolean): Char; inline;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNArray(isTrue: Boolean): string;
const
BoolStr: array [Boolean] of string = ('N', 'Y');
begin
Result := BoolStr[isTrue];
end;
procedure TDBISAM_PERFTest.YNSLoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNS(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNSILoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNSI(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNCLoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNC(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNCILoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNCI(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNALoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNArray(True) <> 'Y' then
Fail('Failed');
end;