完全重复:C++ 中的 i++ 和 ++i 之间是否存在性能差异?
完全重复:循环中 i++ 和 ++i 之间的区别?
哪个更有效,i++ 还是 ++i?
我只在 Java 和 C/C++ 中使用过它,但我真的要求所有实现它的语言。
在大学时,我有一位教授向我们展示了 ++i 更高效,但已经有几年了,我想从 Stack Overflow 社区获得意见。
完全重复:C++ 中的 i++ 和 ++i 之间是否存在性能差异?
完全重复:循环中 i++ 和 ++i 之间的区别?
哪个更有效,i++ 还是 ++i?
我只在 Java 和 C/C++ 中使用过它,但我真的要求所有实现它的语言。
在大学时,我有一位教授向我们展示了 ++i 更高效,但已经有几年了,我想从 Stack Overflow 社区获得意见。
我++:
++我:
通过优化,生成的程序集很可能是相同的,但是 ++i 更有效。
编辑:请记住,在 C++ 中,我可能是支持前缀和后缀 ++ 运算符的任何对象。对于复杂的对象,临时复制成本是不可忽略的。
我会在别处寻找优化潜力。
效率不应该是您关心的问题:它是有意义的。两者是不一样的,除非它们是独立的:一个操作值的前使用,另一个操作后。
诠释我; 我 = 1; cout << i++; //返回1
诠释我; 我 = 1; cout << ++i; //返回2
当含义不重要时,大多数编译器会将 ++i 和 i++(比如在 for 循环中)翻译成相同的机器/VM 代码。
在现代编译器上并不重要。
int v = i++;
是相同的
int v = i;
i = i + 1;
现代编译器会发现它v
没有被使用,并且计算的代码v
是纯的(没有副作用)。然后它将删除v
分配代码并生成此代码
i = i + 1;
这很重要!特别是如果您在使用自定义迭代器协议的 C++ 领域...
++i // the prefered way, unless..
auto j = i++ // this is what you need
您应该使用前缀表示法来避免必要的复制开销,但它仅适用于迭代器,不适用于内置本机类型,无论如何这些只是一条指令。
好吧,在 C++ 中,我相信它们有不同的用途,具体取决于您希望何时更新变量。
效率不应该决定你何时使用一个而不是另一个,但我认为它们将具有相同的效率。
++i 对于 operator++ 的重要实现可能更有效,但即使在这种情况下,编译器也可能能够优化掉中间临时。
++i 不需要临时变量来存储东西。这样想它们:
++i
int preIncrement(int i)
{
i = i + 1;
return i;
}
我++
int i = 5; // as an example
int postIncrement(_i)
{
int temp = _i;
i = _i + 1;
return temp;
}
看?后增量需要一个临时变量。假设编译器不会为您解决所有问题,它几乎肯定会这样做。
当然,更重要的是程序逻辑;如果你太担心这个,你就有可能遇到微优化剧院的悲惨悲剧……:)
除非我遗漏了什么,否则它们应该具有相同的效率。它们都应该产生一个单一的添加指令。这只是添加指令发生位置的问题:在代码行的开头或结尾。
++i 在没有优化的 x86 汇编中比 i++ 少占用一条处理器指令。
没有区别。使用最有意义的结构。
如果您的应用程序运行缓慢,我可以向您保证,它永远不会因为整数增量操作的速度差异。如果是,那么它是编译器中的一个严重错误。应用程序中的速度问题将是算法效率低下、等待 I/O 等等。
不要担心你没有的问题。过早的优化是万恶之源。
++i
更快,因为i++
必须存储i
,然后递增它,然后返回 的存储值i
。++i
只需递增i
然后返回它。
// ++i
i += 1;
return i;
// i++
temp = i;
i += 1;
return temp;
一个独立的“i++;” 或“++i;” 应该生成同样有效的代码。如果您在表达式中使用它,则会出现差异,“副作用”会在其中发挥作用。
也就是说,有一段时间,在“全世界都是 Vax”的时候,编译器很烂,据说 ++i 比 i++ 更有效,即使在“for (i = 0; i < N; + +i)" 类型设置。
这个 Stack Overflow 问题有一个很好的答案:C 中 i++ 和 ++i 之间是否存在性能差异?
我想补充一点,您应该使用更适合您需求的那个。除了在最关键的应用程序中,它并不重要。从学术的角度来看,最好还是编写能够表达您需要并最终优化的代码。
键入 i++ 通常更容易,因此在生产力时间方面更有效。
不过,说真的,如果i是本机数据类型(例如 int、double 等)——没有区别。
如果它是用户定义的类型,则取决于实现,例如
class Type
{
Type& operator ++(){}
const Type& operator ++(int i){}
};
T i;
没有正确或错误的答案。
因为它取决于:
它是如何由编译器实现的。
系统在哪个 CPU 上运行。
ifi
是字节还是i
双字
这取决于上下文,例如:
x = i++
在这种情况下,“x”将等于“i”,只有在那之后,“i”才会加一。
x = ++i
在这种情况下,“i”将加一,然后“x”的新值将分配给“x”。
在“for”循环的情况下,除了性能之外几乎没有明显的差异(++i 更快)。
一般来说,使用 ++i 比使用 i++ 更有效。这样做的简单原因是 ++i 与
我 += 1;
对于 x86 来说,它是一条指令(并且可能是大多数其他广泛使用的架构)。i++ 然而等于
tmp = 我; 我 += 1;
那是因为 'i' 的旧值是 i++ 的计算结果。显然,这比简单的 i += 1; 需要更多的工作;
但如上所述,这对足够聪明的编译器几乎没有影响,因为它将优化未使用的操作。对于许多解释型语言(例如:PHP)来说,++i 的速度增益可能很小;但这种增加可以忽略不计。
Generally, in C++, postfix will require the additional construction of the object incremented, while prefix is applied directly to the object. (Or so I've read.)
As I am unable to attest to how the compiler handles it due to my limited knowledge on the matter, it could be handled for you making it a moot point.
很难准确回答这个问题,因为它取决于编译器/解释器的实现。
但一般来说,您可以说将 i++ 大致扩展为以下指令:
COPY i to tmp
INCREMENT tmp
SAVE tmp as i
而 ++i 将大致扩展到:
LOAD i
INCREMENT i
You can't just say that ++i is faster than i++ since language implementations are pretty smart and they can optimize these instructions when you know that you won't access the temporary value of i++. This usually happens in say a for loop. So in many cases it's just the same.
If you're trying to these kind of micro-optimizations I'd advice you to profile/measure before chosing one over another.