【问题标题】:which is faster: i=i+2 or i+=2? [closed]哪个更快:i=i+2 还是 i+=2? [关闭]
【发布时间】:2012-08-12 00:01:44
【问题描述】:

考虑下面的代码sn-p:

for(i=0;i<10;i+=2) // 1
for(i=0;i<2;i=i+2) // 2

哪个更好用?
它对性能有什么影响吗?

【问题讨论】:

  • 你试过计时吗?你发现了什么?
  • 第二个会更快,因为界限不同。
  • @JensGustedt 你能详细解释一下吗?你是说 2 对 10?
  • 对于任何一半体面的编译器,增量都将是相同的速度(即x+=n;x=x+n; 将产生相同代码)。如果您将变量定义为volatile可能会有一个例外,但这是非常不寻常的,几乎不值得讨论。
  • 让我再次链接到this example,其中 10 多行代码产生 5 条机器指令。不要摆弄低级优化 - 编译器在这方面要好得多

标签: c performance


【解决方案1】:

以下耗时 0.0260015 秒

for (i = 0 ; i < 10000000 ; i += 2)

这需要 0.0170010

for (i = 0 ; i < 10000000 ; i = i + 2)

@MasterID 是正确的,但当我启用“优化代码”时,两者都报告了 0.0150009 秒

【讨论】:

  • 您需要多次运行它。差异可能是由于在后台运行的其他东西和操作系统中断
  • 我不怀疑你的时间安排,但我很确定他们并没有表明后一个代码实际上更慢。在我手头仅有的两个编译器(gcc 和 clang)下,它们都产生完全相同的汇编代码。您几乎可以肯定是在测量噪音。
  • 哇,+1,终于有人真正测试了它:D
  • 当我开始优化时,生成的代码在两者上都是相同的,这支持 @jdehaan 所说的......
  • 并尝试通过在紧密循环中运行代码 50 倍并取平均值来将噪音降至最低。 :D
【解决方案2】:

您的问题没有明确的答案。这取决于您的编译器在其他方面(优化级别,...)和目标平台的智能程度。这不是 C 语言问题。该语言本身并没有或多或少的性能。这仅取决于编译器从中构建的内容。因此,如果性能很重要,请针对您的用例进行测试...

否则我的建议是,按照你觉得更易读的方式来写。

【讨论】:

    【解决方案3】:

    第一个选项至少和第二个一样快。 尽管任何编译优化都会生成相同的汇编代码。

    【讨论】:

      【解决方案4】:

      两者都表达了完全相同的语义,即在 C 语言的抽象机器中完全相同的效果。如果一个比另一个慢,这是编译器中的实现质量缺陷。

      【讨论】:

      • 一些硬件平台处理寄存器读取是读-修改-写操作的一部分,不同于那些不是。我希望在这样一个平台上进行低级编程的高质量实现来处理例如myPORT |= 1 使用单个读取-修改-写入指令,但处理 myPORT = myPORT | 1; 使用单独的读取和写入操作以允许代码可能出于某种原因需要后一种语义,这将是最自然的请求方式他们。
      • @supercat:我不清楚实现对 volatile 对象是否符合要求;对于非易失性的,它根本没有意义,因为根本没有理由期望任何内存访问。在任何情况下,请求此类语义的最自然方式是使用原子对象,而不是秘密依赖特定编译器对形式相同表达式的怪异解释。
      • volatile 对象的精确语义被认为是“实现定义的”,我真的怀疑标准的作者打算禁止实现指定某些特定的复合赋值表达式将以特定方式处理.这个问题出现的地方是在将一个地址分配给两个寄存器的系统上,并将“独立”读取指令处理为访问一个,并将写入和读取-修改-写入指令处理为访问另一个。我不喜欢这样的设计,但有些芯片就是这样工作的。
      • 在例如一个 8051,处理“P0 |= 1”使其表现为“P0outputlatch = P0outputlatch | 1”的唯一方法(这是通常建议的复合赋值)是使用读-修改-写指令。然而,单独读取“P0”将产生“P0inputlatch”寄存器的值。如果出于某种原因代码想要读取 P0inputlatch 的值,设置 LSB,并将其写入 P0outputlatch,这样的操作对于代码“P0 = P0 | 1;”似乎是明智的,但对于“P0 |= 1;”则不适用。 ”。我怀疑任何 8051 编译器都支持 C11 原子,所以它们不是问题。
      • @supercat: 6.5.16.2 ¶3 表示“E1 op = E2 形式的复合赋值等效于简单赋值表达式 E1 = E1 op (E2),除了左值 E1 被评估只有一次......”所以我不相信 volatile 语义细节的实现定义会覆盖两种形式等价的要求。
      猜你喜欢
      • 1970-01-01
      • 2019-04-26
      • 2020-12-28
      • 2015-05-24
      • 2010-10-08
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      相关资源
      最近更新 更多