【问题标题】:What is more efficient, i++ or ++i? [duplicate]哪个更有效,i++ 还是 ++i? [复制]
【发布时间】:2010-10-08 09:01:47
【问题描述】:

完全重复Is there a performance difference between i++ and ++i in C++?
完全重复Difference between i++ and ++i in a loop?


哪个更高效,i++ 还是 ++i?

我只在 Java 和 C/C++ 中使用过它,但我真的要求所有实现它的语言。

在大学时,我有一位教授向我们展示了 ++i 更高效,但已经过去几年了,我想从 StackOverflow 社区获得意见。

【问题讨论】:

标签: java c++ performance post-increment pre-increment


【解决方案1】:

我++:

  • 创建 i 的临时副本
  • 增加 i
  • 返回临时副本

++i :

  • 增加 i
  • 返回我

启用优化后,生成的程序集很可能是相同的,但是 ++i 更有效。

edit:请记住,在 C++ 中,i 可能是支持前缀和后缀 ++ 运算符的任何对象。对于复杂的对象,临时复制成本是不可忽略的。

【讨论】:

  • 在许多处理器上,这两个操作都是一条指令。
  • 这个 Q 我们用 C++ 和 Java 标记。我想知道 Java 有什么不同。
  • +1 取决于 i 是什么......对于整数基元,这些操作很可能是完全相同的事情
  • @Edourad 答:+1 简洁明了的答案!没有编译器的 Javascript 呢?在原型库中,他们说 ++i 更快。
【解决方案2】:

我会在别处寻找优化潜力。

【讨论】:

    【解决方案3】:

    效率不应该是您关心的问题:它是意义。两者相同,除非它们是独立的:一个操作值的预使用,另一个操作后。

    int i; 我 = 1; cout

    int i; 我 = 1; cout

    当意义不重要时,大多数编译器会将 ++i 和 i++(比如在 for 循环中)翻译成相同的机器/VM 代码。

    【讨论】:

      【解决方案4】:

      在现代编译器上没关系。

      int v = i++;  
      

      一样
      int v = i;
      i = i + 1;
      

      现代编译器会发现v 未被使用,计算v 的代码是纯代码(无副作用)。然后它将删除v 和分配代码并生成此代码

      i = i + 1;
      

      【讨论】:

      • 为什么投反对票?如果你不使用副作用,他是对的,没有区别。
      • 我正要问同样的问题。
      • 今天没关系,也许是因为硬件便宜且速度极快。然而,在 10 年前,这个问题是完全有效的。
      • 并非所有软件都可以在最新的台式电脑上运行。
      • 那你也有新问题了。哪个更快,“ADD”或“INC”... :-)(提示:这取决于处理器!)
      【解决方案5】:

      这很重要!特别是如果您在使用自定义迭代器协议的 C++ 领域...

      ++i // the prefered way, unless..
      auto j = i++ // this is what you need
      

      您应该使用前缀表示法来避免必要的复制开销,但它仅适用于迭代器,不适用于内置本机类型,无论如何这些只是一条指令。

      【讨论】:

        【解决方案6】:

        ++i 对于 operator++ 的重要实现可能更有效,但即使在这种情况下,编译器也可能能够优化掉中间临时。

        【讨论】:

          【解决方案7】:

          ++i 不需要临时变量来存储内容。可以这样想:

          ++i

          int preIncrement(int i)
          {
              i = i + 1;
              return i;
          }
          

          i++

          int i = 5; // as an example
          int postIncrement(_i)
          {
              int temp = _i;
              i = _i + 1;
              return temp;
          }
          

          看到了吗?后增量需要一个临时变量。假设编译器不会为您解决所有问题,它几乎肯定会这样做。

          当然,更重要的是程序逻辑;如果你太担心这个,你就有遇到The Sad Tragedy of Micro-Optimisation Theatre 的风险......:)

          【讨论】:

            【解决方案8】:

            嗯,在 C++ 中,我相信它们有不同的用途,具体取决于您希望何时更新变量。

            效率不应决定您何时使用其中一种,但我认为它们在任何一种情况下都会具有相同的效率。

            【讨论】:

            • 对了,++i会先加1再使用值,i++会先使用值再加1。
            【解决方案9】:

            除非我遗漏了什么,否则它们应该具有相同的效率。它们都应该产生一个单一的添加指令。这只是添加指令发生位置的问题:在代码行的开头或结尾。

            【讨论】:

              【解决方案10】:

              ++i 更快,因为i++ 必须存储i,然后递增它,然后返回存储的i 值。 ++i 只是增加 i 然后返回它。

              // ++i
              i += 1;
              return i;
              
              // i++
              temp = i;
              i += 1;
              return temp;
              

              【讨论】:

                【解决方案11】:

                一个独立的“i++;”或“++i;”应该生成同样有效的代码。如果您在表达式中使用它,就会出现不同之处,“副作用”会在其中发挥作用。

                也就是说,有一段时间,在“全世界都是 Vax”的时候,编译器很烂,据说 ++i 比 i++ 更有效,即使在“for (i = 0; i

                【讨论】:

                  【解决方案12】:

                  一般来说,使用 ++i 比使用 i++ 更有效。 原因很简单,就是 ++i 和

                  完全一样

                  i += 1;

                  对于 x86 而言,它是一条指令(并且可能是大多数其他广泛使用的架构)。 然而,i++ 等于

                  tmp = i; i += 1;

                  这是因为 'i' 的旧值是 i++ 求值的结果。显然,这需要比简单的 i += 1; 更多的工作;

                  但如上所述,这对足够聪明的编译器几乎没有影响,因为它会优化未使用的操作。对于许多解释型语言(例如:PHP)来说,++i 的速度增益可能很小;但这种增加可以忽略不计。

                  【讨论】:

                    【解决方案13】:

                    输入 i++ 通常更容易,因此在生产时间方面更有效。

                    说真的,如果 i 是本机数据类型(例如 int、double 等)--没有区别。

                    如果它是用户定义的类型,例如

                    ,则取决于实现
                    class Type
                    {
                        Type& operator ++(){}
                        const Type& operator ++(int i){}
                    };  
                    
                    T i;
                    

                    【讨论】:

                      【解决方案14】:

                      在未经优化的 x86 汇编中,++i 比 i++ 少使用一条处理器指令。

                      【讨论】:

                      • 我想看看你对此的推理。当我将其缩减为独立操作时,我会得到相同数量的处理器指令。
                      • 也许应该用编译器、编译器版本等来限定。
                      【解决方案15】:

                      没有区别。使用最有意义的结构。

                      如果您的应用程序运行缓慢,我可以向您保证,它永远不会因为整数增量操作的速度差异。如果是,那么它是编译器中的一个严重错误。速度 您的应用程序中的问题将是算法效率低下、等待 I/O 等等。

                      不要担心你没有的问题。 Premature optimization is the root of all evil.

                      【讨论】:

                        【解决方案16】:

                        这个堆栈溢出问题有一个很好的答案:Is there a performance difference between i++ and ++i in C?

                        我想补充一点,您应该使用更适合您需求的那个。除了在最关键的应用程序中,它并不重要。从学术的角度来看,最好还是编写能够表达您需要并最终优化的代码。

                        【讨论】:

                          【解决方案17】:

                          没有正确或错误的答案。

                          视情况而定:

                          1. 编译器是如何实现的。

                          2. 系统在哪个 CPU 上运行。

                          3. 如果i是字节或i是双字

                          【讨论】:

                            【解决方案18】:

                            取决于上下文,例如:

                            x = i++
                            

                            在这种情况下,“x”将等于“i”,只有在那之后,“i”才会加一。

                            x = ++i
                            

                            在这种情况下,“i”将加一,然后将“x”的新值分配给“x”。

                            在“for”循环的情况下,除了性能之外几乎没有明显的区别(++i 更快)。

                            【讨论】:

                              【解决方案19】:

                              一般来说,在 C++ 中,postfix 将要求对象的附加构造递增,而prefix 则直接应用于对象。 (或者我读过。)

                              由于我对此事的了解有限,我无法证明编译器如何处理它,因此可以为您处理它,使其成为一个有争议的问题。

                              【讨论】:

                                【解决方案20】:

                                很难准确回答这个问题,因为它取决于编译器/解释器的实现。

                                但一般来说你可以说大致将 i++ 扩展为以下指令:

                                COPY i to tmp
                                INCREMENT tmp
                                SAVE tmp as i
                                

                                而 ++i 将大致扩展到:

                                LOAD i
                                INCREMENT i
                                

                                你不能只说 ++i 比 i++ 快,因为语言实现非常聪明,当你知道你不会访问 i++ 的临时值时,它们可以优化这些指令。这通常发生在一个 for 循环中。所以在很多情况下都是一样的。

                                如果您尝试进行此类微优化,我建议您在选择其中一项之前先进行分析/衡量。

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2015-05-24
                                  • 2014-10-23
                                  • 2013-03-24
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2020-10-17
                                  相关资源
                                  最近更新 更多