完全重复: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 社区获得意见。
我会在别处寻找优化潜力。
效率不应该是你关心的:它是意义。两者是不一样的,除非它们是独立的:一个操作值的预使用,另一个操作。
国际我; 我 = 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
您应该使用前缀表示法来避免必要的复制开销,但它仅适用于迭代器,不适用于内置本机类型,无论如何这些都只是一条指令。
++i 对于 operator++ 的非平凡实现可能更有效,但即使在这种情况下,编译器也可以优化掉中间临时。
++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;
}
看?后增量需要一个临时变量。假设编译器没有为您解决所有问题,它几乎可以肯定会这样做。
当然,更重要的是程序逻辑;如果你太担心这个,你就有可能遇到微优化剧院的悲惨悲剧......:)
好吧,在 C++ 中,我相信它们有不同的用途,具体取决于您希望何时更新变量。
效率不应该决定您何时使用一种而不是另一种,但我认为无论哪种方式它们都具有相同的效率。
除非我遗漏了什么,否则它们应该具有相同的效率。它们都应该导致单个添加指令。这只是添加指令发生位置的问题:在代码行的开头或结尾。
++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)”类型设置。
一般来说,使用 ++i 比使用 i++ 更有效率。这样做的简单原因是 ++i 与
我 += 1;
对于 x86,这是一条指令(可能也是大多数其他广泛使用的架构)。i++ 然而等于
tmp = i; 我 += 1;
那是因为 'i' 的旧值是 i++ 的计算结果。显然,这需要做更多的工作,而不仅仅是 i += 1;
但是如上所述,这对足够聪明的编译器几乎没有影响,因为它将优化未使用的操作。对于许多解释型语言(例如:PHP),++i 的速度提升可能很小;但这种增长是微不足道的。
输入 i++ 通常更容易,因此在生产力时间方面更有效。
不过,说真的,如果i是本机数据类型(例如 int、double 等)——没有区别。
如果它是用户定义的类型,则取决于实现,例如
class Type
{
Type& operator ++(){}
const Type& operator ++(int i){}
};
T i;
在没有优化的情况下,++i 在 x86 汇编中比 i++ 少一条处理器指令。
没有区别。使用最有意义的结构。
如果您的应用程序运行缓慢,我可以向您保证,它永远不会因为整数增量操作的速度差异。如果是,则是编译器中的严重错误。应用程序中的速度问题将是算法效率低下、等待 I/O 等。
不要担心您没有的问题。过早优化是万恶之源。
这个堆栈溢出问题有一个很好的答案:C 中的 i++ 和 ++i 之间有性能差异吗?
我想补充一点,您应该使用更适合您需求的任何一种。除了在最关键的应用程序中,它并不重要。从学术的角度来看,最好编写表达您需要的代码并最终进行优化。
没有正确或错误的答案。
因为它取决于:
编译器是如何实现的。
系统运行在什么 CPU 上。
如果i
是字节或i
双字
这取决于上下文,例如:
x = i++
在这种情况下,'x' 将等于 'i',只有在此之后,'i' 才会增加 1。
x = ++i
在这种情况下,'i' 将增加 1,然后将 'x' 的新值分配给 'x'。
在“for”循环的情况下,除了性能(++i 更快)之外,几乎没有明显的区别。
一般在C++中,postfix会要求对对象进行额外的构造递增,而prefix则是直接应用于对象。(或者我读过。)
由于我对此事的了解有限,我无法证明编译器如何处理它,因此可以为您处理它,使其成为一个有争议的问题。
很难准确回答这个问题,因为它取决于编译器/解释器的实现。
但一般来说你可以大致说一下将 i++ 扩展到以下指令:
COPY i to tmp
INCREMENT tmp
SAVE tmp as i
而 ++i 将大致扩展到:
LOAD i
INCREMENT i
你不能只说 ++i 比 i++ 快,因为语言实现非常聪明,当你知道你不会访问 i++ 的临时值时,它们可以优化这些指令。这通常发生在 for 循环中。所以在很多情况下它是一样的。
如果您正在尝试这些类型的微优化,我建议您在选择一个之前进行分析/测量。
我++:
++我:
通过优化,结果程序集很可能是相同的,但是 ++i 效率更高。
编辑:请记住,在 C++ 中,我可能是支持前缀和后缀 ++ 运算符的任何对象。对于复杂对象,临时复制成本是不可忽略的。