我们的问题是,在C语言中i++和++i的性能有区别吗?

c++的答案是什么?


当前回答

既然你也要求c++,下面是java的基准测试(用jmh制作):

private static final int LIMIT = 100000;

@Benchmark
public void postIncrement() {
    long a = 0;
    long b = 0;
    for (int i = 0; i < LIMIT; i++) {
        b = 3;
        a += i * (b++);
    }
    doNothing(a, b);
}

@Benchmark
public void preIncrement() {
    long a = 0;
    long b = 0;
    for (int i = 0; i < LIMIT; i++) {
        b = 3;
        a += i * (++b);
    }
    doNothing(a, b);
}  

结果表明,即使在某些计算中实际使用了增量变量(b)的值,迫使需要存储额外的值以防止后增量,每个操作的时间也完全相同:

Benchmark                         Mode  Cnt  Score   Error  Units
IncrementBenchmark.postIncrement  avgt   10  0,039   0,001  ms/op
IncrementBenchmark.preIncrement   avgt   10  0,039   0,001  ms/op

其他回答

我想指出Andrew Koenig最近在Code Talk上发表的一篇出色的文章。

http://dobbscodetalk.com/index.php?option=com_myblog&show=Efficiency-versus-intent.html&Itemid=29

在我们公司,我们也在适用的情况下使用++iter的一致性和性能。但Andrew提出了关于意图与性能的忽略细节。有时我们想用iter++而不是++iter。

所以,首先决定你的意图,如果pre或post不重要,那么使用pre,因为它将有一些性能优势,避免创建额外的对象并抛出它。

两者都一样快;) 如果你想在处理器上进行相同的计算,只是计算的顺序不同。

例如,以下代码:

#include <stdio.h>

int main()
{
    int a = 0;
    a++;
    int b = 0;
    ++b;
    return 0;
}

生产以下组件:

0x0000000100000f24 <main+0>: push %rbp 0x0000000100000f25 <main+1>: mov %rsp,%rbp 0x0000000100000f28 <main+4>: movl $0x0,-0x4(%rbp) 0x0000000100000f2f <main+11>: incl -0x4(%rbp) 0x0000000100000f32 <main+14>: movl $0x0,-0x8(%rbp) 0x0000000100000f39 <main+21>: incl -0x8(%rbp) 0x0000000100000f3c <main+24>: mov $0x0,%eax 0x0000000100000f41 <main+29>: leaveq .日志含义 0x0000000100000f42 <main+30>: retq

你可以看到,对于a++和b++,它是一个包含助记符,所以它是相同的操作;)

@wilhelmtell

编译器可以省略临时对象。从另一个线程逐字逐句:

c++编译器允许消除基于堆栈的临时对象,即使这样做会改变程序行为。MSDN链接vc8:

http://msdn.microsoft.com/en-us/library/ms364057 (VS.80) . aspx

@Mark:我删除了我之前的答案,因为它有点轻率,仅凭这一点就应该被打反对票。实际上,我认为这是一个很好的问题,因为它问了很多人的想法。

通常的答案是++i比i++快,毫无疑问,但更大的问题是“什么时候应该关心?”

如果增量迭代器所花费的CPU时间小于10%,那么您可能不会在意。

如果增量迭代器所花费的CPU时间百分比大于10%,则可以查看哪些语句正在进行该迭代。看看你是否可以只增加整数而不是使用迭代器。你有可能做到,虽然在某种意义上可能不太理想,但很有可能你会节省花在那些迭代器上的所有时间。

我曾经见过一个例子,其中迭代器增量消耗了超过90%的时间。在这种情况下,采用整数递增法将执行时间减少了这么多。(即优于10倍加速)

i++有时比++ I快!

对于使用ILP(指令级并行)的x86架构,i++在某些情况下可能优于++i。

为什么?因为数据依赖关系。现代cpu可以并行化很多东西。如果接下来的几个CPU周期对i的增量值没有任何直接依赖,CPU可能会省略微码来延迟i的增量,并将其塞到“空闲插槽”中。这意味着您实际上得到了一个“免费”增量。

我不知道ILE在这种情况下走多远,但我认为如果迭代器变得太复杂,并做指针解引用,这可能不会工作。

下面是Andrei Alexandrescu对这个概念的解释:https://www.youtube.com/watch?v=vrfYLlR8X8k&list=WL&index=5