为什么数组索引比指针快?
指针不应该比数组索引快吗?
指针不应该比数组索引快吗?
**我用了time.h clock_t来测试两个函数,每个循环200万次.
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;
}
}
解决方法
不,从来没有指针应该比数组索引更快.如果其中一个代码比另一个代码快,那主要是因为一些地址计算可能不同.该问题还应提供编译器和优化标志的信息,因为它可能会严重影响性能.
您的上下文中的数组索引(数组绑定不知道)与指针操作完全相同.从编译器的角度来看,它只是指针算术的不同表达.以下是Visual Studio 2010中优化的x86代码的示例,具有完全优化和无内联.
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看起来更快,因为指令数量较少,但是这两段代码基本相同.两者都最终使用代表站,这是一个x86的重复(循环)指令.唯一的区别是因为计算循环限制. myIndex中的for循环具有行程计数大小(即,不需要计算).但是,myPointer需要一些计算来获取for循环的行程计数.这是唯一的区别.重要的循环操作是一样的.因此,差异可以忽略不计.
总而言之,myPointer和myIndex在优化代码中的性能应该是一样的.
如果在编译时已知数组的边界,例如int A [constant_expression],那么这个数组的访问可能比指针一个快得多.这主要是因为阵列访问没有从pointer analysis问题.编译器可以完全计算固定大小的数组上的计算和访问的依赖关系信息,因此可以进行高级优化,包括自动并行化.
然而,如果计算是基于指针的,编译器必须执行指针分析以进一步优化,这在C/C++中是非常有限的.它通常以指针分析的保守结果结束,并产生一些优化机会.