比较运算符的速度

发布于 2024-11-16 06:01:51 字数 206 浏览 5 评论 0原文

在诸如...以及任何语言之类的语言中,两个运算符都适用于 <和 <= (及其相反)存在。哪个会更快,它们是如何解释的?

if (x <= y) { 废话; }

或者

if (x < y + 1) { 废话; }

In languages such as... well anything, both operators for < and <= (and their opposites) exist. Which would be faster, and how are they interpreted?

if (x <= y) { blah; }

or

if (x < y + 1) { blah; }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

对岸观火 2024-11-23 06:01:51

假设没有编译器优化(大假设),第一个会更快,因为 <= 是由单个 jle 指令实现的,而后者需要加法后跟 jl指令。

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

Assuming no compiler optimizations (big assumption), the first will be faster, as <= is implemented by a single jle instruction, where as the latter requires an addition followed by a jl instruction.

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

秋日私语 2024-11-23 06:01:51

就性能而言,我根本不担心这个。以 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 index index index index index index index index index index index number_of_elements 测试
  • 使用指向元素的指针迭代数组应该使用 ptr (array + number_of_elements) 测试

实际上,即使在 C 语言中,我现在也倾向于使用 ptr != (array + number_of_elements) 因为我已经习惯了 STL 迭代器,其中 <关系赢得了工作。

事实上,如果我在 for 循环条件中看到 <= 测试,我会仔细查看 - 通常存在潜伏的错误。我认为这是一种反模式。

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

I wouldn't worry about this at all as far as performance goes. Using C as an example, on a simple test I ran with GCC 4.5.1 targeting x86 (with -O2), the (x <=y ) operation compiled to:

    // 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

and the (x < y + 1) operation compiled to:

    // 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:

So you might have a difference of a jump around a jump or so, but you should really only be concerned about this kind of thing for the odd time where it really is a hot spot. Of course there may be differences between languages and what exactly happens might depend on the type of objects that are being compared. But I'd still not worry about this at all as far as performance is concerned (until it became a demonstrated performance issue - which I'll be surprised if it ever does for more than once or twice in my lifetime).

So, I think the only two reasons to worry about which test to use are:

  • correctness - of course, this trumps any other consideration
  • style/readabilty

While you might not think there's much to the style/readability consideration, I do worry about this a little. In my C and C++ code today, I'd favor using the < operator over <= because I think loops tend to terminate 'better' using a < than a <= test. So, for example:

  • iterating over an array by index, you should typically use an index < number_of_elements test
  • iterating over an array using pointers to elements should use a ptr < (array + number_of_elements) test

Actually even in C, I now tend to use a ptr != (array + number_of_elements) since I've gotten used to STL iterators where the < relation won work.

In fact, if I see a <= test in a for loop condition, I take a close look - often there's a bug lurking. I consider it an anti-pattern.

Noe I'll grant that a lot of this may not hold for other languages, but I be surprised if when I'm using another language that there's ever a performance issues I'll have to worry about because I chose to use < over <=.

不可一世的女人 2024-11-23 06:01:51

什么数据类型?

如果 yINT_MAX,则无论 x 是什么(假设 x 是相同或更小的类型),而第二个表达式始终为 false

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

What data-type?

If y is INT_MAX, then the first expression is true no matter what x is (assuming x is the same or smaller type), while the second expression is always false.

If the answer doesn't need to be right, you can get it even faster.

笔落惊风雨 2024-11-23 06:01:51

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

Have you considered that both those arguments are different? In case x and y are floating point numbers - they may not give the same result. That is the reason both comparison operators exists.

高冷爸爸 2024-11-23 06:01:51

更喜欢第一个。

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

Prefer the first one.

In some languages with dynamic types the running environment has to figure out what the type of y is and execute the appropriate + operator.

熟人话多 2024-11-23 06:01:51

如果你把这个问题保留得如此模糊,就会导致这个问题成为一个无法回答的问题。除非有软件和硬件可供测量,否则无法评估性能 - 什么语言?什么语言实现?什么目标CPU架构?话

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

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

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

Leaving this as vague as you have has caused this to be an unanswerable question. Performance cannot be evaluated unless you have software and hardware to measure - what language? what language implementation? what target CPU architecture? etc.

That being said, both <= and < are often identical performance-wise, because they are logically equivalent to > and >=, just with swapped destinations for the underlying goto's (branch instructions), or swapped logic for the underlying "true/false" evaluation.

If you're programming in C or C++, the compiler may be able to figure out what you're doing, and swap in the faster alternative, anyway.

Write code that is understandable, maintainable, correct, and performant, in that order. For performance, find tools to measure the performance of your whole program, and spend your time wisely. Optimize bottlenecks only until your program is fast enough. Spend the time you save by making better code, or making more cool features :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文