我试图通过示例说明前缀增量比后缀增量更有效。
理论上这是有道理的:i++ 需要能够返回未递增的原始值并因此存储它,而++i 可以返回递增的值而不存储先前的值。
但是在实践中是否有一个很好的例子来证明这一点?
我尝试了以下代码:
int array[100];
int main()
{
for(int i = 0; i < sizeof(array)/sizeof(*array); i++)
array[i] = 1;
}
我使用 gcc 4.4.0 像这样编译它:
gcc -Wa,-adhls -O0 myfile.cpp
我又做了一次,将后缀增量改为前缀增量:
for(int i = 0; i < sizeof(array)/sizeof(*array); ++i)
两种情况下的结果是相同的汇编代码。
这有点出乎意料。似乎通过关闭优化(使用-O0),我应该看到展示概念的不同之处。我错过了什么?有更好的例子来说明这一点吗?
最佳答案
在一般的情况下,后增量会产生一个前增量不会的拷贝。当然,这将在大量情况下被优化掉,并且在不是复制操作的情况下可以忽略不计(即,对于内置类型)。
这是一个小例子,显示了后增量的潜在低效率。
#include <stdio.h>
class foo
{
public:
int x;
foo() : x(0) {
printf( "construct foo()\n");
};
foo( foo const& other) {
printf( "copy foo()\n");
x = other.x;
};
foo& operator=( foo const& rhs) {
printf( "assign foo()\n");
x = rhs.x;
return *this;
};
foo& operator++() {
printf( "preincrement foo\n");
++x;
return *this;
};
foo operator++( int) {
printf( "postincrement foo\n");
foo temp( *this);
++x;
return temp;
};
};
int main()
{
foo bar;
printf( "\n" "preinc example: \n");
++bar;
printf( "\n" "postinc example: \n");
bar++;
}
优化构建的结果(实际上由于 RVO 在后增量情况下删除了第二次复制操作):
construct foo()
preinc example:
preincrement foo
postinc example:
postincrement foo
copy foo()
一般来说,如果您不需要后增量的语义,为什么要冒险发生不必要的拷贝?
当然,最好记住自定义 operator++() - 无论是 pre 还是 post 变体 - 都可以自由地返回它想要的任何东西(甚至做它想做的任何事情),我想有很多不遵循通常的规则。偶尔我会遇到返回“void
”的实现,这使得通常的语义差异消失了。
关于c++ - i++ 比++i 效率低,如何显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1116735/