1

( ProDelphiプロファイラーを使用して) 私のアプリをプロファイリングすることで、この関数がより高速であれば、より良いパフォーマンスを達成できることがわかりました。

function BooleanToYN(isTrue: Boolean): string;
begin
  if isTrue then
    Result := 'Y'
  else
    Result := 'N';
end;

このコードを見たとき、すでに「最適化」されていると思いました。あなたの意見でそれをスピードアップする方法はありますか?他にコメントはありますか?これはレガシー コードです。私が書いたわけではありません。もちろん、アプリの作成方法を変更することを検討できますが、とにかくこの単純な関数を高速化する方法があれば (別の既製の Delphi 関数を使用する可能性があります)、それは素晴らしいことです。

4

2 に答える 2

6

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;
于 2013-10-14T14:15:41.740 に答える