delphi – 为什么优化器不会在循环中消除High?
发布时间:2020-12-15 04:27:52 所属栏目:大数据 来源:网络整理
导读:人们表示,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
人们表示,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,ebx 004045B2 8B45FC mov eax,[ebp-$04] 004045B5 E8E6FAFFFF call @DynArrayHigh 004045BA 3BD8 cmp ebx,eax 004045BC 750A jnz $004045c8 004045BE 8B45FC mov eax,$fffffff7 004045C8 43 inc ebx 004045C9 4E dec esi 004045CA 75E6 jnz $004045b2 004045CC 33C0 xor eax,eax 004045BC 750A jnz $004045c8 再次,同样的调用@DynArrayHigh生成… 解决方法
这不是一个答案,而是一个(自毁)的评论:)
在我看来,编译器不能尝试优化这个. 为什么编译器试图优化(非确定性)高功能而不是其他功能? (如长度) 循环中的动态数组长度可能会由SetLenth或其他方式更改.该数组可能会在运行时重新初始化,您的代码可能依赖于: for i := 0 to High(arr) do begin if (i = High(arr)) then arr[i] := -9 else if foo() then arr := nil; // or SetLength(arr,0); if High(arr) = -1 then Exit; // arr is nil end; 你怎么建议应该优化?编译器应该甚至尝试优化吗? 如果您希望优化代码,请自行优化.e.g: var arrHigh: Integer; arrHigh := High(arr); for i := 0 to arrHigh do if i = arrHigh then... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |