检查布尔语句的表达式顺序是否会影响性能

时间:2010-09-15 17:06:15

标签: optimization conditional boolean

如果我有一个布尔表达式来检查

(A && B)

如果发现A是假的,语言是否会费心去检查B?这会因语言而异吗?

我问的原因是我想知道是否检查B即使A是假的也不会

if (A) {
  if(B) {

  } else {
     // code x
  }
} else {
  // code x
}

快一点
if (A && B) {

} else {
   // code x
}

6 个答案:

答案 0 :(得分:4)

这取决于语言。大多数语言都会将A && B实现为短路运算符,这意味着如果A求值为false,则永远不会计算B。有一个detailed list on Wikipedia

答案 1 :(得分:1)

许多语言(包括几乎所有卷括号语言,如C / C ++ / Java / C#)都提供短路布尔评估。在这些语言中,如果A为假,则不会评估B.您需要查看(或询问)这是否适用于您的特定语言,或者是否有办法(例如,VB有AndAlso)。

如果您发现您的语言不支持它,您还需要考虑评估B的成本是否值得维护两个相同的代码片段 - 以及缓存占用空间可能增加一倍(更不用说所有额外的分支)都来自每次重复。

答案 2 :(得分:1)

几乎每种语言都实现了一种名为short-circuit evaluation的东西,这意味着,如果A为假,则A(& B)将不会评估B.如果你写:

,这也会生效
if (A || B) {
    ...
}

和A是真的。如果B可能需要很长时间才能加载,这是值得记住的,但通常不需要担心。

作为一段历史,在我看来,这是LISP的一个痛处,因为这样的代码:

(if (and (= x 5) (my-expensive-query y)) "Yes" "No")

不是由函数组成,而是所谓的“特殊形式”(即“和”在这里无法解析)。

答案 3 :(得分:1)

这将取决于语言编译所述代码的方式。 任何都是可能的:)

你想知道某种语言吗?

答案 4 :(得分:1)

简而言之,没有。双分支涉及各种形式的分支预测。如果A和B很容易评估,那么如果(A& B)以非短路方式进行(A& B)比如果(A)进行(B)则更快。此外,您在第二种形式中复制了代码。这实际上总是(每个规则的例外......我猜)不好,甚至比任何收益都差。

其次,这是您为语言解释器,JIT或编译器提供的一种微优化。

答案 5 :(得分:0)

正如其他人所说,这取决于语言和/或编译器。对我来说,我不关心短路与否的速度或速度,重复代码的需要是一个交易杀手。

如果A和B实际上是具有副作用的调用(即它们不仅仅返回一个适合比较的值),那么我认为这些调用应该变成可变赋值,然后在比较中使用。无论您是否总是需要这些副作用或只是有条件地要求它们,如果您不依赖于是否存在短路,代码将更具可读性。

关于可读性的最后一点是基于我的感觉,即减少引用外部文档的需要提高了可读性。当你已经拥有必要的词汇时,阅读一本需要字典查找的新词比阅读同一本书更具挑战性。在这种情况下,短路是不可见的,所以任何需要查看的人都不会知道他们需要查找它。