我有一个微优化问题。我有3种方法来处理typed-Pointer(数组)。哪一个更好?
// [view drawViewHierarchyInRect:view.frame afterScreenUpdates:NO]; // comment this line
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; // use this line
for I:=0 to ArrCount-1 do
begin // I:Var is unused in below-block
Inc(P) ; // P is typed-Pointer
// do somethings
end;
for I:=ArrCount-1 downto 0 do
begin // I:Var is unused in below-block
Inc(P) ; // P is typed-Pointer
// do somethings
end;
答案 0 :(得分:4)
我将对这个问题给出的答案比你期望的更平凡。这些变体中最快的是等待它的时间最快。
完全可信的是,在不同的架构中,您会发现不同的变体获胜。
也可以想到,根据循环体内的不同,不同的变体会获胜。
循环体很可能需要足够的时间,相比之下环路本身可以忽略不计。
总之,这取决于。因为只有你知道身体内部会发生什么,只有你能回答特定的问题。
顺便说一句,如果循环体没有引用循环变量,那么编译器会重新写入升序循环,就像它是一个降序循环一样。所以实际上这里可能只有两个变种。实际上,这可能意味着所有三种变体都会产生相同的编译代码!
一些建议:
现在,如果你想让我做一个猜测,我预测对于任何不仅仅是一个微不足道nop
的循环体,你会发现很难找到这些变体之间的任何可衡量的差异。
我也看到你正在使用指针遍历一个数组。您可能会发现,如果此代码是瓶颈,并且循环体只处理此数组迭代,那么使用arr[]
索引比指针算法更有效。但同样,它取决于许多事情,你必须分析,并查看编译器生成的代码。
答案 1 :(得分:-1)
很有趣,但是看反汇编窗口,速度取决于天气是循环中使用的循环变量。
1)不使用 - 代码几乎相同:
Project17.dpr.12: for i := 0 to 3 do
0040914D B804000000 mov eax,$00000004
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 $00409152
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 $0040915b
2)使用 - 第一个变体更快一点,因为xor
比mov
更快:
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,$04
00409155 75F8 jnz $0040914f
Project17.dpr.15: for i := 3 downto 0 do
00409157 B803000000 mov eax,$00000003
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,-$01
00409162 75F8 jnz $0040915c
您可以自己检查第三种变体。
PS:我正在使用D2007进行此测试。