比较运算符的速度

问题描述 投票:0回答:6

在诸如...以及任何语言之类的语言中,两个运算符都代表 < and <= (and their opposites) exist. Which would be faster, and how are they interpreted?

如果(x<= y) { blah; }

如果(x< y + 1) { blah; }

performance language-agnostic operator-keyword
6个回答
7
投票

假设没有编译器优化(大假设),第一个会更快,如 <= is implemented by a single

jle
指令,而后者需要加法,后跟
jl
指令。

http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Jump_if_Less


3
投票

就性能而言,我根本不担心这一点。以 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
测试,我会仔细观察 - 通常存在潜伏的错误。我认为这是一种反模式。

不,我承认其中很多内容可能不适用于其他语言,但如果当我使用另一种语言时我必须担心性能问题,我会感到惊讶,因为我选择使用

< 
超过
<=


2
投票

什么数据类型?

如果

y
INT_MAX
,则无论
true
是什么(假设
x
是相同或更小的类型),第一个表达式都是
x
,而第二个表达式始终是
false

如果答案不需要正确,您可以更快地得到答案。


0
投票

您是否认为这两个论点是不同的?如果 x 和 y 是浮点数 - 它们可能不会给出相同的结果。这就是两个比较运算符存在的原因。


0
投票

更喜欢第一个。

在某些具有动态类型的语言中,运行环境必须弄清楚 y 的类型并执行适当的 + 运算符。


0
投票

让这个问题变得如此模糊,导致这是一个无法回答的问题。除非有软件和硬件可供测量,否则无法评估性能 - 什么语言?什么语言实现?什么目标CPU架构?等等

话虽这么说,

<=
<
在性能方面通常是相同的,因为它们在逻辑上等同于
>
>=
,只是交换了底层goto(分支指令)的目的地,或者交换了逻辑用于基本的“真/假”评估。

如果您使用 C 或 C++ 进行编程,编译器也许能够弄清楚您在做什么,并换成更快的替代方案。

按顺序编写可理解、可维护、正确和高性能的代码。对于性能,找到衡量整个程序性能的工具,并明智地花费时间。仅优化瓶颈直到您的程序足够快。将节省的时间花在编写更好的代码或制作更酷的功能上:)

© www.soinside.com 2019 - 2024. All rights reserved.