就性能而言,我根本不会担心这一点。以 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 循环条件中看到 <= 测试,我会仔细查看 - 通常潜伏着一个错误。我认为这是一种反模式。
不,我承认其中很多可能不适用于其他语言,但如果我使用另一种语言时,我不得不担心性能问题,因为我选择使用< 超过 <=。