为什么我的数组索引比指针快 [英] How come my array index is faster than pointer
问题描述
为什么数组索引比指针快?指针不应该比数组索引快吗?
Why the array index is faster than pointer? Isn't pointer supposed to be faster than array index?
** 我使用 time.h clock_t 测试了两个函数,每个循环 200 万次.
** i used time.h clock_t to tested two functions, each loop 2 million times.
Pointer time : 0.018995
Index time : 0.017864
void myPointer(int a[], int size)
{
int *p;
for(p = a; p < &a[size]; p++)
{
*p = 0;
}
}
void myIndex(int a[], int size)
{
int i;
for(i = 0; i < size; i++)
{
a[i] = 0;
}
}
推荐答案
不,指针永远不会比数组索引更快.如果其中一个代码比另一个更快,主要是因为某些地址计算可能不同.该问题还应提供编译器和优化标志的信息,因为它会严重影响性能.
No, never ever pointers are supposed to be faster than array index. If one of the code is faster than the other, it's mostly because some address computations might be different. The question also should provide information of compiler and optimization flags as it can heavily affect the performance.
上下文中的数组索引(数组边界未知)与指针操作完全相同.从编译器的角度来看,它只是指针运算的不同表达.以下是 Visual Studio 2010 中优化的 x86 代码示例,完全优化,无内联.
Array index in your context (array bound is not known) is exactly identical to the pointer operation. From a viewpoint of compilers, it is just different expression of pointer arithmetic. Here is an example of an optimized x86 code in Visual Studio 2010 with full optimization and no inline.
3: void myPointer(int a[], int size)
4: {
013E1800 push edi
013E1801 mov edi,ecx
5: int *p;
6: for(p = a; p < &a[size]; p++)
013E1803 lea ecx,[edi+eax*4]
013E1806 cmp edi,ecx
013E1808 jae myPointer+15h (13E1815h)
013E180A sub ecx,edi
013E180C dec ecx
013E180D shr ecx,2
013E1810 inc ecx
013E1811 xor eax,eax
013E1813 rep stos dword ptr es:[edi]
013E1815 pop edi
7: {
8: *p = 0;
9: }
10: }
013E1816 ret
13: void myIndex(int a[], int size)
14: {
15: int i;
16: for(i = 0; i < size; i++)
013E17F0 test ecx,ecx
013E17F2 jle myIndex+0Ch (13E17FCh)
013E17F4 push edi
013E17F5 xor eax,eax
013E17F7 mov edi,edx
013E17F9 rep stos dword ptr es:[edi]
013E17FB pop edi
17: {
18: a[i] = 0;
19: }
20: }
013E17FC ret
一目了然,myIndex
看起来更快,因为指令数量更少,但是,两段代码本质上是一样的.两者最终都使用 rep stos
,这是 x86 的重复(循环)指令.唯一的区别在于循环边界的计算.myIndex
中的 for
循环具有行程计数 size
原样(即,不需要计算).但是,myPointer
需要一些计算来获得 for
循环的行程计数.这是唯一的区别.重要的循环操作是一样的.因此,差异可以忽略不计.
At a glance, myIndex
looks faster because the number of instructions are less, however, the two pieces of the code are essentially the same. Both eventually use rep stos
, which is a x86's repeating (loop) instruction. The only difference is because of the computation of the loop bound. The for
loop in myIndex
has the trip count size
as it is (i.e., no computation is needed). But, myPointer
needs some computation to get the trip count of the for
loop. This is the only difference. The important loop operations are just the same. Thus, the difference is negligible.
总而言之,myPointer
和 myIndex
在优化代码中的性能应该是相同的.
To summarize, the performance of myPointer
and myIndex
in an optimized code should be identical.
仅供参考,如果数组的边界在编译时是已知的,例如,int A[constant_expression]
,那么对该数组的访问可能比指针快得多.这主要是因为数组访问不受指针分析问题的影响.编译器可以完美地计算固定大小数组上计算和访问的依赖信息,因此可以进行高级优化,包括自动并行化.
FYI, if the array's bound is known at compile time, e.g., int A[constant_expression]
, then the accesses on this array may be much faster than the pointer one. This is mostly because the array accesses are free from the pointer analysis problem. Compilers can perfectly compute the dependency information on computations and accesses on a fixed-size array, so it can do advanced optimizations including automatic parallelization.
然而,如果计算是基于指针的,编译器必须执行指针分析以进一步优化,这在 C/C++ 中非常有限.它通常以指针分析的保守结果结束,并导致一些优化机会.
However, if computations are pointer based, compilers must perform pointer analysis for further optimization, which is pretty much limited in C/C++. It generally ends up with conservative results on pointer analysis and results in a few optimization opportunity.
这篇关于为什么我的数组索引比指针快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!