i ++比++ i效率低,如何展示?

csc*_*hol 15 c++ optimization prefix postfix-operator

我试图通过示例显示前缀增量比后缀增量更有效.

理论上这是有道理的:i ++需要能够返回未增加的原始值并因此存储它,而++我可以返回增量值而不存储先前的值.

但是有一个很好的例子可以在实践中证明这一点吗?

我尝试了以下代码:

int array[100];

int main()
{
  for(int i = 0; i < sizeof(array)/sizeof(*array); i++)
    array[i] = 1;
}
Run Code Online (Sandbox Code Playgroud)

我使用gcc 4.4.0编译它,如下所示:

gcc -Wa,-adhls -O0 myfile.cpp
Run Code Online (Sandbox Code Playgroud)

我再次这样做,后缀增量更改为前缀增量:

for(int i = 0; i < sizeof(array)/sizeof(*array); ++i)
Run Code Online (Sandbox Code Playgroud)

在两种情况下,结果都是相同的汇编代码.

这有些出乎意料.似乎通过关闭优化(使用-O0)我应该看到显示概念的差异.我错过了什么?有更好的例子来展示这个吗?

Mic*_*urr 23

一般情况下,后增量将导致复制,其中预增量不会.当然,这将在大量情况下被优化,并且在不是复制操作的情况下将是可忽略的(即,对于内置类型).

这是一个小例子,显示了后增量的潜在低效率.

#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++;
}
Run Code Online (Sandbox Code Playgroud)

优化构建的结果(实际上由于RVO而在后增量情况下删除了第二个复制操作):

construct foo()

preinc example: 
preincrement foo

postinc example: 
postincrement foo
copy foo()
Run Code Online (Sandbox Code Playgroud)

通常,如果您不需要后增量的语义,为什么要冒这个不必要的副本?

当然,最好记住一个自定义操作符++() - 前置或后置变量 - 可以随意返回它想要的任何内容(甚至可以做任何想做的事情),我想有很多不符合通常的规则.偶尔我会遇到返回" void"的实现,这会使通常的语义差异消失.

  • 这个例子清楚地说明了i ++的问题 - 如果我是一个复杂的类型,副本很昂贵(也许是一个复杂的引用计数迭代器),那么必须避免复制. (3认同)

小智 8

你不会看到整数有任何区别.你需要使用迭代器或post和prefix真正做不同的东西.而你需要把所有的优化,不脱!

  • 无论何时对任何事情进行基准测试,您都需要让编译器生成最好的代码.在优化水平较低的情况下,各种因素(如寄存器使用不良)可能会起作用并扭曲结果.在此之前发布基准测试时,我一直被这种方式所困扰. (16认同)

Jas*_*ton 5

我喜欢遵循"说出你的意思"的规则.

++i简单地增加.i++增量具有特殊的,非直观的评估结果.我只i++在我明确要求这种行为时使用,并++i在所有其他情况下使用.如果你遵循这种做法,当你看到i++代码时,很明显后期增量行为确实是有意的.

  • 我敢打赌,如果这个语言被命名为++ C,那么人们会更频繁地这样做. (8认同)
  • 也许它被称为C++,因为它在使用某种方式时仍然像C一样. (5认同)
  • "当你在代码中看到i ++时,很明显后期增量行为确实是有意的." 你必须是记住差异的特殊少数人之一;-) (2认同)