在诸如...以及任何语言之类的语言中,两个运算符都代表 < and <= (and their opposites) exist. Which would be faster, and how are they interpreted?
如果(x<= y) { blah; }
或
如果(x< y + 1) { blah; }
假设没有编译器优化(大假设),第一个会更快,如 <= is implemented by a single
jle
指令,而后者需要加法,后跟 jl
指令。
http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Jump_if_Less
就性能而言,我根本不担心这一点。以 C 为例,在一个简单的测试中,我使用面向 x86 的 GCC 4.5.1(带有
-O2
)运行,(x <=y )
操作编译为:
// if (x <= y) {
// printf( "x <= y\n");
// }
//
// `x` is [esp+28]
// `y` is [esp+24]
mov eax, DWORD PTR [esp+24] // load `y` into eax
cmp DWORD PTR [esp+28], eax // compare with `x`
jle L5 // if x < y, jump to the `true` block
L2:
// ...
ret
L5: // this prints "x <= y\n"
mov DWORD PTR [esp], OFFSET FLAT:LC1
call _puts
jmp L2 // jumps back to the code after the ` if statement
以及
(x < y + 1)
操作编译为:
// if (x < y +1) {
// printf( "x < y+1\n");
// }
//
// `x` is [esp+28]
// `y` is [esp+24]
mov eax, DWORD PTR [esp+28] // load x into eax
cmp DWORD PTR [esp+24], eax // compare with y
jl L3 // jump past the true block if (y < x)
mov DWORD PTR [esp], OFFSET FLAT:LC2
call _puts
L3:
所以你可能会有跳跃左右的差异,但你实际上应该只在它确实是热点的奇怪时间关心这种事情。当然,语言之间可能存在差异,具体发生的情况可能取决于正在比较的对象的类型。但就性能而言,我仍然根本不担心这一点(直到它成为一个明显的性能问题 - 如果它在我的一生中出现超过一两次,我会感到惊讶)。
所以,我认为担心使用哪个测试的唯一两个原因是:
虽然您可能认为风格/可读性没有太多考虑,但我确实有点担心这一点。在今天的 C 和 C++ 代码中,我更喜欢使用
<
运算符而不是 <=
,因为我认为使用 <
比使用 <=
测试“更好”地终止循环。因此,例如:
index < number_of_elements
测试ptr < (array + number_of_elements)
测试实际上,即使在 C 语言中,我现在也倾向于使用
ptr != (array + number_of_elements)
,因为我已经习惯了 STL 迭代器,其中 <
关系可以发挥作用。
事实上,如果我在
<=
循环条件下看到 for
测试,我会仔细观察 - 通常存在潜伏的错误。我认为这是一种反模式。
不,我承认其中很多内容可能不适用于其他语言,但如果当我使用另一种语言时我必须担心性能问题,我会感到惊讶,因为我选择使用
<
超过<=
。
什么数据类型?
如果
y
是 INT_MAX
,则无论 true
是什么(假设 x
是相同或更小的类型),第一个表达式都是 x
,而第二个表达式始终是 false
。
如果答案不需要正确,您可以更快地得到答案。
您是否认为这两个论点是不同的?如果 x 和 y 是浮点数 - 它们可能不会给出相同的结果。这就是两个比较运算符存在的原因。
更喜欢第一个。
在某些具有动态类型的语言中,运行环境必须弄清楚 y 的类型并执行适当的 + 运算符。
让这个问题变得如此模糊,导致这是一个无法回答的问题。除非有软件和硬件可供测量,否则无法评估性能 - 什么语言?什么语言实现?什么目标CPU架构?等等
话虽这么说,
<=
和<
在性能方面通常是相同的,因为它们在逻辑上等同于>
和>=
,只是交换了底层goto(分支指令)的目的地,或者交换了逻辑用于基本的“真/假”评估。
如果您使用 C 或 C++ 进行编程,编译器也许能够弄清楚您在做什么,并换成更快的替代方案。
按顺序编写可理解、可维护、正确和高性能的代码。对于性能,找到衡量整个程序性能的工具,并明智地花费时间。仅优化瓶颈直到您的程序足够快。将节省的时间花在编写更好的代码或制作更酷的功能上:)