0

我是编程新手,我注意到一个反复出现的模式是我必须在while循环中使用的频繁否定,例如while (!isEmpty())

如果有一个“直到”循环,例如做某事直到条件为真,这不是更好的性能吗?我确实意识到否定发生在寄存器上并且速度非常快,但看起来仍然可以避免。

或者也许汇编语言的某些东西使得使用当前建立的方法更可取,即使它经常需要否定?

4

1 回答 1

1

否定很可能不会以需要任何时间的方式明确发生。

首先,天真的“while”实现在 x86 上看起来像这样

_loophead:
  call _isEmpty
  test eax, eax ; return value is in eax
  jnz _loopend  ; break out of loop if condition is not zero
  ... ; loop body here
  jmp _loophead
_loopend:

那里没有实际的否定,只是jnz“如果不是零就跳跃”。什么不是零?影响“标志”的最后一件事 - 上面的测试测试isEmpty().

一个更好的“while”实现(因为每次迭代只需要 1 个分支)看起来像

  jmp _looptest
_loopstart:
  ... ; loop body
_looptest:
  call _isEmpty
  test eax, eax
  jz _loopstart  ; continue loop if condition is zero

否定,当它存在时,不需要额外的时间/指令/空间。许多其他处理器也是如此。

此外,如果_isEmpty可以内联,则条件很可能甚至不会真正存在于寄存器中,它将成为标志状态的一部分(特殊寄存器中的单个位)。诸如“布尔值是 0 或 1 的整数”之类的东西是概念语义的一部分,并且通常在实际实现中被优化。你通常不需要那个 0/1 值——大多数时候你要做的第一件事就是把它放回标志寄存器中,这样你就可以在它上面分支​​。

即使是非常早期的 C 编译器也特别努力将“用作条件的布尔”编译为比从中生成 0/1 整数更有效的代码。

于 2013-06-22T21:53:50.870 回答