【发布时间】:2008-10-23 19:41:25
【问题描述】:
我记得从 C 天起我们就被鼓励使用
i > -1
而不是
i >= 0
因为性能。
这仍然适用于 C# .NET 世界吗?在当今的编译器中使用其中一种对性能有何影响?即编译器是否足够聪明,可以为您优化这些?
(顺便尝试在 Stack Overflow 上的问题字段中输入问题“使用 >= 或 >”,看看会发生什么。)
【问题讨论】:
我记得从 C 天起我们就被鼓励使用
i > -1
而不是
i >= 0
因为性能。
这仍然适用于 C# .NET 世界吗?在当今的编译器中使用其中一种对性能有何影响?即编译器是否足够聪明,可以为您优化这些?
(顺便尝试在 Stack Overflow 上的问题字段中输入问题“使用 >= 或 >”,看看会发生什么。)
【问题讨论】:
不,没有与比较运算符相关的性能问题。无论如何,任何好的编译器都会优化这种微不足道的东西。
我不确定您从哪里得到使用“i > -1”而不是“i >= 0”的建议。在 x86 架构上,您使用哪个没有区别:任何一种情况都需要两条指令……一条用于比较,一条用于跳转:
;; if (i > -1) {
cmp eax, -1
jle else
then:
...
else:
;; if (i >= 0) {
cmp eax, 0
jl else
then:
...
else:
在我知道的大多数 RISC 架构上,“i >= 0”实际上可能更快,因为通常有一个专用的零寄存器,而“i > -1”可能需要加载一个常量。例如,MIPS 只有一个
// if (i >= 0) { (assuming i is in register %t0)
stl $t1, $0, $t0 // in C: t1 = (0 < t0)
beq $t1, $0, else // jump if t1 == 0, that is if t0 >= 0
nop
then:
...
else:
// if (i > -1) { (assuming i is in register %t0)
addi $t2, $0, -1 // in C: t2 = -1
stl $t1, $t2, $t0 // in C: t1 = (t2 < t0) = (-1 < t0)
bne $t1, $0, else // jump if t1 != 0, that is if t0 > -1
nop
then:
...
else:
因此,在幼稚的一般情况下,在 MIPS 上执行“i >= 0”实际上会快一条指令。当然,RISC 代码的优化程度如此之高,以至于编译器可能会将这些指令序列中的任何一个更改得几乎无法识别:-)
所以...简短的回答是不不不,没有区别。
【讨论】:
(no no no, no difference) = !(!(!(!difference))) = !(!difference)) = difference ;)
除了任何体面的编译器都会做正确的事情这一事实之外,除了在现代架构中> 和 >= 比较之间没有速度差异这一事实之外,更大的图景表明这是一个“微- 优化”在绝大多数情况下不会影响运行时性能。
在比较的情况下,无论您以哪种方式编写它,它通常都不会影响可读性,但在某些情况下,选择一个边界而不是另一个边界会更清晰:例如,
if (length >= str.size())
对
if (length > str.size() - 1)
我不了解你,但我会随时选择选项 1。 :-) 在不会明显影响性能的情况下,例如这种情况,更易读的选项应该会胜出。
【讨论】:
这里有一个非常相似的问题(没有暗示批评 - 正如你所说,搜索符号很棘手):"Should one use < or <= in a for loop"
(是的,我碰巧能够很容易地找到它,因为我的答案得到了很多赞成...)
基本上,做最易读的事情。有人正确猜测改变最易读的形式将解决性能问题(无需分析器的帮助)的那一天就是我停止谈论性能的那一天:)
【讨论】:
不,您不再需要这样做了。是的,编译器变得更加智能,这两个表达式没有性能差异。
【讨论】:
我记得从 C 天开始,我们就被鼓励使用 .... 因为性能。
你确定对此吗?早在 70 年代初,我就使用过计算机(是的,在我父亲的膝盖上……),我从未见过 CPU 不能处理 >= 和 > 一样快。 (IBM360 演讲中的 BH “Branch High”与 BNL “Branch Not Low”)。
【讨论】:
对于一些将 >= 分解为 2 个比较的可疑脚本语言来说,这可能是正确的,但是无论谁鼓励你将它用于 C ......嗯......你可能应该努力忘记他们曾经告诉过的一切你。
【讨论】:
这让我想起了使用 ++i 而不是 i++(前置增量与后置增量)的建议,因为它据说快了一条指令。 (我忘记了我最初是从哪里读到这个的,但它可能是 C/C++ 用户日志或 Dobb 博士的日志,但我似乎无法找到网络参考。)
我严重怀疑 > 或 >= 更快或更慢;而是为了清晰起见编写代码。
作为旁注,我开发了对预增量 (++i) 运算符的偏好,即使原因现在可能已过时。
【讨论】:
对于大于零,它必须进行两次检查。它检查负位是否关闭,并检查零位是否关闭。
对于大于或等于零,只需要检查负位是否关闭,因为我们不关心零位是打开还是关闭。
【讨论】: