for-loop(downto,Reversed) vs for-loop(increase mode) vs while-loop in Delphi

for-loop(downto,Reversed) vs for-loop(increase mode) vs while-loop in Delphi

我有一个微优化问题。我有 3 种处理 typed-Pointer(array) 的方法。哪个更好?

1

for I:=0 to ArrCount-1 do
begin  // I:Var is unused in below-block
  Inc(P) ; // P is typed-Pointer
  // do somethings 
end;

2

for I:=ArrCount-1  downto  0 do
begin  // I:Var is unused in below-block
  Inc(P) ; // P is typed-Pointer
  // do somethings 
end;

3

While ArrCount>0 do
begin  
  Inc(P) ; // P is typed-Pointer
  
  // do somethings 
  Dec(ArrCount);
end;

我对这个问题的回答可能比您预期的要平凡得多。这些变体中最快的是等待它的时间最快的运行。

完全有可能在不同的体系结构上您会发现不同的变体获胜。

还可以想象,根据循环 body 中的内容,不同的变体将获胜。

循环的 body 也很可能需要足够的时间,相比之下循环本身可以忽略不计。

总之,视情况而定。由于只有您知道 body 内部发生了什么,所以只有您可以回答具体问题。

顺便说一句,如果循环 body 没有引用循环变量,那么编译器 re-writes 升序循环就好像它是降序循环一样。所以这里实际上可能只有两种变体。事实上,这可能意味着所有三个变体都会导致相同的编译代码!

一些建议:

  • 切勿在没有分析的情况下进行优化。
  • 永远不要优化不是瓶颈的代码。

现在,如果你想让我猜一猜,我预测对于任何比微不足道 nop 更重要的循环 body,你会发现很难找到任何可测量的差异在这些变体之间。

我还看到您正在使用指针遍历数组。您可能会发现,如果此代码是瓶颈,并且如果循环 body 仅处理此数组迭代,则使用 arr[] 索引比指针算法更有效。但同样,它取决于很多因素,您必须分析并查看编译器生成的代码。

有趣,但是看反汇编window速度取决于天气是循环内部使用的循环变量。

1) 未使用 - 代码几乎相同:

Project17.dpr.12: for i := 0 to 3 do
0040914D B804000000       mov eax,[=10=]000004
Project17.dpr.13: Inc(j);
00409152 43               inc ebx
Project17.dpr.12: for i := 0 to 3 do
00409153 48               dec eax
00409154 75FC             jnz [=10=]409152

Project17.dpr.15: for i := 3 downto 0 do
00409156 B8FCFFFFFF       mov eax,$fffffffc
Project17.dpr.16: Inc(j);
0040915B 43               inc ebx
Project17.dpr.15: for i := 3 downto 0 do
0040915C 40               inc eax
0040915D 75FC             jnz [=10=]40915b

2) 使用 - 第一个变体快一点,因为 xormov 快:

Project17.dpr.12: for i := 0 to 3 do
0040914D 33C0             xor eax,eax
Project17.dpr.13: Inc(j, i);
0040914F 03D8             add ebx,eax
00409151 40               inc eax
Project17.dpr.12: for i := 0 to 3 do
00409152 83F804           cmp eax,
00409155 75F8             jnz [=11=]40914f

Project17.dpr.15: for i := 3 downto 0 do
00409157 B803000000       mov eax,[=11=]000003
Project17.dpr.16: Inc(j, i);
0040915C 03D8             add ebx,eax
0040915E 48               dec eax
Project17.dpr.15: for i := 3 downto 0 do
0040915F 83F8FF           cmp eax,-
00409162 75F8             jnz [=11=]40915c

您可以自己检查第三个变体。

PS: 本次测试我使用的是D2007