什么是有效的检查:等于或不等于

What is efficient to check: equal to or not equal to?

本文关键字:不等于 检查 有效 什么      更新时间:2023-10-16

我想知道,如果我们有if-else条件,那么检查什么在计算上更有效:使用等于运算符还是不等于运算符?有什么区别吗?

例如,以下哪一种

在计算上是有效的,下面的两种情况都会做同样的事情,但哪一种更好(如果有任何区别)?

案例1:

if (a == x)
{
    // execute Set1 of statements
}
else
{
    // execute Set2 of statements
}

案例2:

if (a != x)
{
    // execute Set2 of statements
}
else
{
    // execute Set1 of statements
}

这里的假设是大多数时候(比如 90% 的情况)a等于 xax 都是无符号整数类型。

通常,

使用哪个运算符对性能无关紧要。但是,建议分支时,if 语句最可能的结果排在第一位。

通常你应该考虑的是;编写这段代码的最简单、最清晰的方法是什么? 恕我直言,第一个,积极的是最简单的(不需要!

在性能方面没有区别,因为代码可能会编译为相同的东西。(当然,在Java的JIT中应该)

对于 Java,JIT 可以优化代码,因此分支预测首选最常见的分支。

在这个简单的情况下,它没有区别。(假设ax是基本类型)如果它们是具有超载operator ==operator !=的类类型,它们可能会有所不同,但我不会担心。

对于后续循环:

if ( c1 )   { }
else if ( c2 ) { }
else ...

最有可能的条件应该放在第一位,以防止对其他条件进行无用的评估。(同样,这里不适用,因为您只有一个else)。

GCC 提供了一种通知编译器表达式可能结果的方法:

if (__builtin_expect(expression, 1))
…

这个内置值的计算值为 expression ,但它通知编译器可能的结果是 1(布尔值true)。要使用它,您应该尽可能清楚地编写expression(对于人类),然后将第二个参数设置为最有可能成为结果的值。

没有区别。

x86 CPU 架构有两个用于条件跳转的操作码

JNE (jump if not equal)
JE (jump if equal)

通常它们都需要相同数量的 CPU 周期。

即使他们不会,您也可以期望编译器为您进行如此微不足道的优化。写下最易读的内容,以及使您的意图更清晰的内容,而不是担心微秒。

如果你曾经设法编写一段 Java 代码,可以证明以一种方式比另一种方式更有效率,你应该发布你的结果,并对你观察到差异的任何实现提出问题。

更重要的是,仅仅问这种问题应该是不对劲的征兆:这表明你把注意力和精力集中在代码的错误方面。实际应用程序性能总是受到架构不足的影响;从来没有像这样的担忧。

早期优化是万恶之源

即使是分支预测,我认为你也不应该太在意这一点,除非真的有必要。

正如彼得所说,使用最简单的方法。

让编译器/优化器完成它的工作。一般的经验法则(现在大多数情况下)是源代码应该以最易读的方式表达您的意图。你把它写给另一个人(而不是计算机),一年后你自己或你的队友,他们需要以更少的努力理解你的代码。

它应该不会对性能产生任何影响,但您可以考虑最容易阅读的内容。然后,当您回顾代码或有人查看代码时,您希望它易于理解。

如果第一个条件在大多数情况下为真,则它具有一点优势(从可读性的角度来看)。以最好的方式编写条件。否定条件不会从速度中受益

大多数处理器使用电气门进行相等/不等式检查,这意味着一次检查所有位。因此,它应该没有什么区别,但你想真正优化你的代码,最好自己对事情进行基准测试并检查结果。
如果您想知道这样优化是否值得,请想象一下,您会对屏幕中的每个像素或类似场景进行多次检查。恕我直言,优化总是值得的,即使只是为了教自己养成好习惯;)

只有您最初使用的非消极方法似乎是最好的。

确定的唯一方法是对两个版本进行编码并测量其性能。 如果差异只有百分比左右,请使用更清楚地传达意图的版本。

不太可能看到两者之间的显着差异。

它们之间的性能差异可以忽略不计。因此,只需考虑代码的可读性。为了可读性,我更喜欢在 If 语句中有更多代码行的那个。

if (a == x) { 
    // x lines of code
} else {
    // y lines of code where y < x
}