人々は、Delphi は整数演算で非常に優れた最適化されたコードを生成すると言いました。Delphi 2007 で次の例を試してみると、コンパイラによって生成されたアセンブリ コードが表示されます。
program p1000;
{$APPTYPE CONSOLE}
procedure test;
var
arr: array of integer;
i: integer;
begin
SetLength(arr, 100);
for i := 0 to High(arr) do
begin
if (i = High(arr)) then
begin
arr[i] := -9;
end;
end;
end;
begin
test;
readln;
end.
ビルド構成が DEBUG に設定されている場合、次のように、ブレークポイントを設定し、ショートキーCtrl+ Alt+Dを使用してそのアセンブリ コードを表示できます。
Project3.dpr.11: for i := 0 to High(arr) do
004045A1 8B45FC mov eax,[ebp-$04]
004045A4 E8F7FAFFFF call @DynArrayHigh
004045A9 8BF0 mov esi,eax
004045AB 85F6 test esi,esi
004045AD 7C1D jl $004045cc
004045AF 46 inc esi
004045B0 33DB xor ebx,ebx
Project3.dpr.13: if (i = High(arr)) then
004045B2 8B45FC mov eax,[ebp-$04]
004045B5 E8E6FAFFFF **call @DynArrayHigh**
004045BA 3BD8 cmp ebx,eax
004045BC 750A jnz $004045c8
Project3.dpr.15: arr[i] := -9;
004045BE 8B45FC mov eax,[ebp-$04]
004045C1 C70498F7FFFFFF mov [eax+ebx*4],$fffffff7
Project3.dpr.17: end;
004045C8 43 inc ebx
Project3.dpr.11: for i := 0 to High(arr) do
004045C9 4E dec esi
004045CA 75E6 jnz $004045b2
私が理解できる限りHigh()
、ループ内で関数を何度も呼び出します。
Project3.dpr.13: if (i = High(arr)) then
004045B2 8B45FC mov eax,[ebp-$04]
004045B5 E8E6FAFFFF **call @DynArrayHigh**
004045BA 3BD8 cmp ebx,eax
ビルド構成が RELEASE に設定されている場合、ブレークポイントは使用できないため、F8/を押しF7てループにステップ インします。
00404589 6A64 push $64
0040458B 8D45FC lea eax,[ebp-$04]
0040458E B901000000 mov ecx,$00000001
00404593 8B1554454000 mov edx,[$00404554]
00404599 E8B6FCFFFF call @DynArraySetLength
0040459E 83C404 add esp,$04
004045A1 8B45FC mov eax,[ebp-$04]
004045A4 E8F7FAFFFF call @DynArrayHigh
004045A9 8BF0 mov esi,eax
004045AB 85F6 test esi,esi
004045AD 7C1D jl $004045cc
004045AF 46 inc esi
004045B0 33DB xor ebx,ebx
004045B2 8B45FC mov eax,[ebp-$04]
004045B5 E8E6FAFFFF call @DynArrayHigh
004045BA 3BD8 cmp ebx,eax
004045BC 750A jnz $004045c8
004045BE 8B45FC mov eax,[ebp-$04]
004045C1 C70498F7FFFFFF mov [eax+ebx*4],$fffffff7
004045C8 43 inc ebx
004045C9 4E dec esi
004045CA 75E6 jnz $004045b2
004045CC 33C0 xor eax,eax
004045BC 750A jnz $004045c8
繰り返しますが、同じことcall @DynArrayHigh
が生成されます...
私の質問は、コンパイラがこれを最適化できないのはなぜですか? High()
配列サイズは変更されないため、値をローカルレジスタ/変数に保存するだけです。