【发布时间】:2011-06-19 10:05:14
【问题描述】:
我想优化一段具有这种结构的代码:
while (i > 0) do begin
Dec(i);
这看起来效率低下,所以我尝试这样做:
while (Dec(i) >= 0) do begin
这不起作用,因为 Dec 是一个过程而不是一个函数。
所以我改写成:
procedure Withloop;
var
....
function Decr(var a: integer): integer; inline;
begin
Dec(a);
Result:= a;
end;
...
while (Decr(i) >= 0) do begin
但这会被编译成:
SDIMAIN.pas.448: while (Decr(i) >= 0) do begin
00468EE5 8BC4 mov eax,esp
00468EE7 E8D0FEFFFF call Decr <<--- A call??
00468EEC 85C0 test eax,eax
00468EEE 0F8D12FFFFFF jnl $00468e06
00468EF4 EB01 jmp $00468ef7
但是在程序的另一部分,它内联了一个函数就好了。
我可以使用什么经验法则(或硬性规则)来了解 Delphi 将遵守 inline 指令?
【问题讨论】:
-
与你的说法相反——我认为你的第一段代码在这里是最有效的。
-
你为什么要优化所有事物的循环计数器?整数运算非常便宜,每次迭代只发生一次递减,所以如果循环做了任何有趣的事情,那将花费绝大多数时间。这甚至没有涉及这个循环是否是一个很好的优化候选者的问题(它是一个热点还是只占总运行时间的 0.5%)。如果您对机器代码的外观有所了解,您会发现前两个版本可以很容易地编译为相同的代码。优化失败。
-
@delnan,我有点讨厌人们认为你是个白痴。当然循环是
hot,否则我不会打扰。测试做得更多,但我将其简化为本质。我也知道你不能内联 asm 函数,所以合乎逻辑的选择:function Decr(var a: integer): integer; inline; begin asm DEC EAX end; end;已经过时了。 -
我很难相信你会比第一段代码做得更好。为什么第二个代码块会比第一个代码块编译得更快,即使它是有效的?我不认为德尔南没有假设你是个白痴。很多人都提出了基于严重误解的优化问题。既然你没有说这个特定的循环是你代码中的热点,我们怎么知道。现在,如果你在循环中做了任何事情,那么 while 测试和 dec 将是微不足道的,所以也许 delnan 有一点。
-
@Johan 你错了。 for 循环可以运行 0 次。始终确保您的循环计数器是有符号整数。事实上总是使用
Integer。
标签: delphi optimization inline delphi-2007