c++ - i++ 比++i 效率低,如何显示?

标签 c++ optimization prefix postfix-operator

我试图通过示例说明前缀增量比后缀增量更有效。

理论上这是有道理的: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/

相关文章:

c - 为什么 gcc 不删除对非 volatile 变量的检查?

Mysql查询优化

javascript - 如何使用 Javascript 设置样式转换?

http - 什么是cdn前缀而不是网址中的www

optimization - Erlang:优化复杂的qlc

python - 从一组(相似的)字符串中确定前缀

c++ - 在 for 循环中倒计时

java - 使用大多数 Java 代码制作可执行文件,但可能会添加另一种语言

c++ - 如何获取ipmi fru原始数据?

c++ - 多线程服务器