C ++指针与数组的[]运算符比较?

时间:2014-01-09 02:38:35

标签: c++ arrays pointers

我一直在阅读一个book,它说通过指针算法访问数组元素要比[]运算符快得多。简而言之,this代码比this代码更快。 这本书没有说明原因。即使它提供了显着的速度改进,是否可以使用这种指针算法?

#include <iostream>
using namespace std;

int main() {
    // your code goes here
    double *array = new double[1000000];
    for(int i = 0; i < 1000000; i++)
    {
        array[i] = 0;//slower?
    }
    delete[] array;
    return 0;
}

#include <iostream>
using namespace std;

int main() {
    // your code goes here
    double *array = new double[1000000];
    for(int i = 0; i < 1000000; i++)
    {
        *(array + i) = 0;//faster?
    }
    delete[] array;
    return 0;
}

修改

引自书第369页,最后一行

  

指针访问方法比数组索引快得多。

6 个答案:

答案 0 :(得分:5)

不,他们完全是一回事。我绝对建议你尽快放弃那本书pick another one up

即使存在性能差异,x[12]*(x + 12)的清晰度也更为重要。

答案 1 :(得分:2)

数组索引只是指针算术的语法糖。您的编译器会将a[i]归结为*((a) + (i))。同意,远离那本书!

有关更深入的解释,请参阅

  1. SO Answer
  2. Eli Bendersky's explanation

答案 2 :(得分:2)

完全没有区别,如果我们转到draft C++ standard部分5.2.1 订阅 1 说(强调我的):

  

[...] 表达式E1 [E2]与*((E1)+(E2))相同[注:有关*和*的详细信息,请参见5.3和5.7 +和8.3.4有关数组的详细信息。 - 后注]

答案 3 :(得分:1)

垃圾。普通阵列上的a[x]衰减为*(a + x)。字面上会有0个性能差异。

答案 4 :(得分:1)

这本书是完全错误的 - 特别是如果这些是他们给出的实际例子。体面编译器可能会为这两种方法生成相同的代码,即使没有优化也会产生相同的性能。

如果没有优化,或者使用80年代的编译器,您可能会遇到某些类型的指针算法的性能差异,但这些示例甚至不代表这种情况。这些示例基本上只是同一事物的不同语法。

这是一个可能有性能差异的例子(相对于未改变的数组索引情况):

int main() {
  // your code goes here
  double *array = new double[1000000], *ptr = array;
  for(; ptr < array + 1000000; ptr++)
  {
    *ptr = 0;
  }
  return 0;
}

这里,您不是每次都通过循环索引基指针,而是每次递增指针。理论上,您可以避免索引中隐含的乘法,从而产生更快的循环。在实践中,任何体面的编译器都可以将索引形式减少为加法形式,而在现代硬件上,索引所隐含的sizeof(double)乘法通常是免费的,如lea之类的指令(加载有效地址)因此,即使在汇编级别,索引版本也可能不会更慢(实际上可能更快,因为它避免了循环携带的依赖性,并且更适合于别名分析)。

答案 5 :(得分:-1)

你的两个表格是相同的,你并没有真正做指针运算。

指针形式为:

double * array= new double[10000000] ;
double * dp= array ;

for ( int i= 0 ; ( i < 10000000 ) ; i ++, dp ++ )
{
  * dp= 0 ;
}

听到,dp中的地址通过添加移动到下一个地址。在其他形式中,通过乘以i时间sizeof(double)并将其添加到array,每个地址都会计算出地址。它的乘数在历史上比加法慢。