什么是有效的检查:等于或不等于
What is efficient to check: equal to or not equal to?
我想知道,如果我们有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
等于 x
。 a
和 x
都是无符号整数类型。
使用哪个运算符对性能无关紧要。但是,建议分支时,if 语句最可能的结果排在第一位。
通常你应该考虑的是;编写这段代码的最简单、最清晰的方法是什么? 恕我直言,第一个,积极的是最简单的(不需要!
在性能方面没有区别,因为代码可能会编译为相同的东西。(当然,在Java的JIT中应该)
对于 Java,JIT 可以优化代码,因此分支预测首选最常见的分支。
在这个简单的情况下,它没有区别。(假设a
和x
是基本类型)如果它们是具有超载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
}
- 为什么 std::round(sin(pi/6)) 不等于 1?
- 为什么复制构造函数不需要检查输入对象是否指向自身?
- 你怎么编码,如果x不等于一个数字,程序就会退出
- u张量模型输出不等于预期输出
- 虽然不等于陈述和/或差异
- 这种关系不等于定义良好的表达式吗?
- C ,二进制树的高度,而不是检查我的子树是否为空,而是在检查我的子树是否是叶子节点.抛出分割故障
- OpenGL 版本不等于支持的着色器版本
- 我可以检查字符串是否以空结尾,但不能检查它是否尚未以空结尾
- 两个 4 位位字段加起来不等于一个字节的大小 - 如何修复?
- 如果整数不等于 0,则将其减小为 1
- C 循环虽然不等于任何两个值
- vb.net单不等于c float
- 如何获取C编译器#Error如果大小(struct ..)不等于给定的数字
- C++ 而语句不等于检查
- DontSpawnIf碰撞不会检查由 SpawnActor 函数生成的 actor
- 有没有办法检查int是否不等于数组中的所有值?(C )
- 整数数组中的元素数量不等于其大小
- 获取不等于特定值的向量的第一个N元素
- 什么是有效的检查:等于或不等于