如果不使用结果值,i++和++i之间是否有性能差异?


当前回答

我总是喜欢预增量,然而……

我想指出的是,即使在调用运算符++函数的情况下,如果函数得到内联,编译器将能够优化掉临时函数。由于操作符++通常很短,并且经常在头文件中实现,因此它很可能被内联。

因此,出于实际目的,这两种形式的性能之间可能没有太大差异。然而,我总是喜欢预增量,因为它似乎更好地直接表达我想说的,而不是依赖于优化器来解决它。

此外,给优化器更少的任务可能意味着编译器运行得更快。

其他回答

请不要让“哪个更快”的问题成为使用哪个的决定因素。你可能永远不会关心那么多,此外,程序员的阅读时间比机器的时间要昂贵得多。

使用任何对阅读代码的人最有意义的方法。

首先:在C中i++和++i之间的差异是可以忽略的。


到细节。

1. 众所周知的c++问题:++i更快

在c++中,如果i是具有重载自增操作符的某种对象,则++i的效率更高。

为什么? 在++i中,对象首先递增,然后可以作为const引用传递给任何其他函数。如果表达式是foo(i++),这是不可能的,因为现在增量需要在foo()调用之前完成,但旧的值需要传递给foo()。因此,编译器被迫在对原始i执行自增操作符之前复制i。额外的构造函数/析构函数调用是不好的部分。

如上所述,这不适用于基本类型。

2. 鲜为人知的事实是:i++可能更快

如果不需要调用构造函数/析构函数,这在C中总是如此,那么++i和i++应该同样快,对吗?不。他们的速度几乎一样快,但可能有一些小的差异,这是大多数其他答案的错误理解。

How can i++ be faster? The point is data dependencies. If the value needs to be loaded from memory, two subsequent operations need to be done with it, incrementing it, and using it. With ++i, the incrementation needs to be done before the value can be used. With i++, the use does not depend on the increment, and the CPU may perform the use operation in parallel to the increment operation. The difference is at most one CPU cycle, so it is really neglegible, but it is there. And it is the other way round then many would expect.

@Mark 即使编译器允许优化(基于堆栈的)变量的临时副本,并且gcc(在最近的版本中)正在这样做, 这并不意味着所有编译器都会这样做。

我刚刚用我们在当前项目中使用的编译器测试了它,4个中有3个没有优化它。

永远不要假设编译器是正确的,特别是如果可能更快,但永远不会更慢的代码很容易阅读。

如果你的代码中没有一个操作符的愚蠢实现:

我喜欢++i胜过i++。

如果你担心微观优化,这里有一个额外的观察。递减循环“可能”比递增循环更有效(取决于指令集架构,例如ARM),给定:

for (i = 0; i < 100; i++)

在每个循环中,你将有一个指令:

i加1。 比较i是否小于100。 如果i小于100,则为条件分支。

而递减循环:

for (i = 100; i != 0; i--)

循环将有一个指令用于以下每一个:

递减i,设置CPU寄存器状态标志。 一个依赖于CPU寄存器状态(Z==0)的条件分支。

当然,这只适用于递减到零!

记得ARM系统开发人员指南。

在C语言中,如果结果未被使用,编译器通常可以将它们优化为相同。

然而,在c++中,如果使用提供自己的++操作符的其他类型,前缀版本可能比后缀版本更快。因此,如果不需要后缀语义,最好使用前缀操作符。