数组的C++指针与[]运算符的比较
C++ pointer comparison with []operator for arrays?
我读过一本书,书中说通过指针算术访问数组元素比[]运算符快得多。简而言之,这个代码比这个代码快。这本书没有说明原因。即使这样的指针算法在速度上有显著提高,使用它是否明智?
#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页,倒数第二行
指针访问方法比数组索引快得多。
即使存在任何性能差异,x[12]
相对于*(x + 12)
的清晰度也要重要得多。
数组索引只是指针运算的语法糖。您的编译器将把a[i]
归结为*((a) + (i))
。同意了,滚出那本书!
有关更深入的解释,请参阅
- SO回答
- Eli Bendersky的解释
如果我们进入C++标准草案5.2.1
订阅段落1说(emphasis mine):
[…]表达式E1[E2](根据定义)与*((E1)+(E2))相同[注意:*和+的详细信息请参见5.3和5.7,数组的详细信息见8.3.4。--尾注]
Utter垃圾。平面阵列上的CCD_ 6衰减为CCD_。实际上将存在0性能差异。
这本书完全错了——尤其是如果这些是他们给出的实际例子。即使没有优化,体面的编译器也可能为这两种方法生成相同的代码,并且它们将具有相同的性能。
如果没有优化,或者使用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
(加载有效地址)等指令的一部分,因此,即使在程序集级别,索引版本也可能不会更慢(事实上可能更快,因为它避免了循环携带的依赖性,并且也更好地进行混叠分析)。
您的两个表单是相同的,您实际上并不是在进行指针运算。
指针形式为:
double * array= new double[10000000] ;
double * dp= array ;
for ( int i= 0 ; ( i < 10000000 ) ; i ++, dp ++ )
{
* dp= 0 ;
}
听说,dp
中的地址通过添加移动到下一个地址。在其他形式中,地址是通过乘以i
时间大小(double)并将其添加到array
来计算的。从历史上看,乘法比加法慢。
- 为什么比较运算符如此快速
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 关于 std::min, std::max 中的比较运算符的混淆
- 三向比较运算符成员与非成员实现
- 标准::可选枚举的比较运算符
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- C++分数混合比较运算符错误
- <<运算符优先级与字符串比较
- 不能将重载比较运算符与 Catch 测试一起使用
- 重构使用动态强制转换的 std::set 的比较运算符
- ">"运算符和"<"运算符如何进行字符串比较?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- C++使用关系运算符比较字符串
- 为什么使用 and 运算符比较 if 语句中的 2 个对象会抛出错误,而使用 2 if 语句则不会
- 使用关系运算符比较指针意味着什么
- 运算符<比较多个字段
- 运算符==比较两个不同的类
- 使用==运算符比较字符串到0
- 使用'if'语句和"<<"时的结果错误,'>>'运算符比较 3 个整数