【问题标题】:Why is ++i more efficient than i++? [duplicate]为什么 ++i 比 i++ 更有效? [复制]
【发布时间】:2013-03-24 14:45:18
【问题描述】:

根据Google C++ Style Guide,“当返回值被忽略时,'pre' 形式 (++i) 的效率永远不会低于 'post' 形式 (i++),而且通常效率更高。 "

该指南继续解释原因,但我并不完全理解。想法?也许有人可以提供这个概念的例子?

【问题讨论】:

  • 对于内置类型,它们是相同的。使用自定义类型,前缀自然不那么复杂。
  • ++i 立即增加 'i' 的值,因此在一个时钟周期内该值增加为新值。而 i++ 需要 2 个时钟周期。就效率而言,考虑到时钟周期的速度,这是值得商榷的。
  • @maditya 这个问题是针对 C 而不是 C++。答案不同。
  • 是的,只是在发布后注意到,对此感到抱歉。删除评论会不会很混乱?

标签: c++ for-loop while-loop do-while


【解决方案1】:

i++ 递增i 并返回i 的初始值。这意味着:

int i = 1;
i++; // == 1 but i == 2

但是++i返回的是实际增加的值:

int i = 1;
++i; // == 2 and i == 2 too, so no need for a temporary variable

在第一种情况下,编译器必须创建一个临时变量(使用时)以返回 1 而不是 2(在它当然不是常量而是动态值的情况下,从例如打电话)。

在第二种情况下,它不必。所以保证第二种情况至少同样有效。

通常,编译器能够将第一种情况优化为第二种情况,但有时可能无法做到。

无论如何,我们所说的影响可以忽略不计。

但在更复杂的对象上,例如iterators-like 对象,如果迭代数百万次,具有临时状态可能会相当慢。

经验法则

除非您特别想要后缀语义,否则请使用前缀版本。

【讨论】:

    【解决方案2】:

    引用自:

    http://www.parashift.com/c++-faq/increment-pre-post-speed.html

    ++i 有时比 i++ 快,而且永远不会慢于 i++。

    对于像 int 这样的内在类型,这无关紧要:++i 和 i++ 的速度相同。对于像迭代器这样的类类型,++i 可能比 i++ 快,因为后者可能会复制 this 对象。

    i++ 的开销(如果有的话)可能不会产生任何实际影响,除非您的应用程序受 CPU 限制。例如,如果您的应用程序大部分时间都在等待某人单击鼠标、执行磁盘 I/O、网络 I/O 或数据库查询,那么浪费几个 CPU 周期不会影响您的性能。然而,键入 ++i 和键入 i++ 一样容易,所以为什么不使用前者,除非您确实需要 i 的旧值。

    因此,如果您将 i++ 编写为语句而不是较大表达式的一部分,为什么不直接编写 ++i 呢?你永远不会失去任何东西,有时你会有所收获。老 C 程序员习惯于编写 i++ 而不是 ++i。例如,他们会说,

    for (i = 0; i < 10; i++) .... 
    

    由于这将 i++ 用作语句,而不是更大表达式的一部分,因此您可能希望使用 ++i 代替。为了对称,我个人提倡这种风格,即使它不会提高速度,例如,对于内在类型和带有返回 void 的后缀运算符的类类型。

    【讨论】:

      【解决方案3】:

      i++ - 使用 i 后值递增 ++i - 值立即递增。

      可能存在性能差异,因为 ++i 要求 i 立即递增,句号。 i++ 继续建议在增加之前可能需要 i 。该值可能会在增加之前存储在某处。

      【讨论】:

        【解决方案4】:

        递增(或递减)运算符涉及两个操作:递增和取两个值(旧值或新值)之一作为表达式的结果。区别在于拿哪一个。

        如果您采用预制件,您首先会增加值,然后再采用新的值。

        在你讲述后表单时,你获取旧值,保留它,递增它,将新值放入旧位置并返回旧值。这听起来更复杂 - 确实如此。

        但是如果表达式的返回值被忽略,那应该没什么区别,不管你有内置类型还是对象。

        【讨论】:

          【解决方案5】:

          对于迭代器和其他模板类型,使用预增量。

          【讨论】:

          • 问题是关于“为什么会这样”。
          • 这是因为后增量(或减量)需要制作 i 的副本,这是表达式的值。如果 i 是迭代器或其他非标量类型,复制 i 可能会很昂贵。
          【解决方案6】:

          这是因为当你后增量时,你必须:

          1. 同时更改值和
          2. 将旧值分配给其他值。

          只需保留该变量的两份副本,复制和删除需要额外的时间...

          【讨论】:

            猜你喜欢
            • 2014-10-23
            • 2020-03-09
            • 2012-08-25
            • 2011-10-06
            • 2017-10-23
            • 2011-02-22
            • 2010-10-08
            • 2013-05-22
            • 1970-01-01
            相关资源
            最近更新 更多