8

我理解下面的区别(至少对于 Java):

if( true || false ) // short-circuiting boolean operator
if( true | false )  // non-short-circuiting boolean operator

但我的问题是,在处理布尔表达式时是否有任何理由使用非短路运算符?是否有一些不会被视为不良做法的性能优势或用途?

4

9 回答 9

11

您可能想要使用非短路运算符的一个原因是您是否以某种方式依赖于函数的副作用。例如。

boolean isBig(String text) {
  System.out.println(text);
  return text.length() > 10;
}

...
if( isBig(string1) || isBig(string2) ){
   ...
}

如果您不关心是否println执行,那么您应该使用上面的短路操作。但是,如果您希望始终打印两个字符串(因此取决于副作用),那么您需要使用非短路运算符。

实际上,您几乎总是希望使用短路运算符。依赖表达式中的副作用通常是不好的编程习惯。

一个例外是在非常低级别或对性能敏感的代码中。短路运算符可能会稍微慢一些,因为它们会导致程序执行中的分支。此外,使用位运算符还允许您将 32 或 64 个并行布尔运算作为单个整数运算进行,这非常快。

于 2013-08-21T05:25:15.857 回答
9

如果您的代码对性能足够敏感并且操作足够便宜,那么使用非短路可以更快。这是因为使用||涉及执行分支,并且分支预测未命中可能非常昂贵。由于|执行计算和检查变量可以更快,避免分支预测失误。

注意:这是一个微优化,除非被多次调用,否则您很少会看到差异。

于 2013-08-21T05:32:25.417 回答
6

short-circuit,这意味着如果没有必要,他们不会评估右手边。例如,如果&&左侧为假,则无需评估右侧。换句话说,||如果左边为真,则无需评估右手边。

non-short总是评估双方。

显然,short-circuit运营商有好处。

而非短的好处,可以在这里找到答案。Java/Scala 中的非短路逻辑(布尔)运算符有很好的用途吗?

也考虑这个例子

  while (status){ // status is boolean value
          if(!a | result){// a and result are boolean value
              result=getResult(); // result can change time to time
          } 
      }

我们现在需要检查双方。

于 2013-08-21T05:19:54.950 回答
6

我的问题更侧重于寻找使用的好处 | 仅处理布尔值时

考虑以下情况

while ( !credentialvalid() | (loginAttempts++ < MAX) ) {

    // tell something to user.

}

在这种情况下 |需要,因为我也必须增加尝试次数:)

于 2013-08-21T05:27:13.597 回答
5

唯一不应该使用非短路运算符的地方是当您希望执行第二条语句时,通常在条件语句中不应该出现这种情况

,不短路没有性能,但是短路绝对有好处

于 2013-08-21T05:18:48.390 回答
3

第三个声明

if( 10 | 11 )       // bitwise operator

会产生编译错误。只有布尔值可以放在 if 语句中。

如果您使用的是 Eclipse 之类的 IDE,它会自动显示第二个表达式,即 || 之后。作为短路布尔运算符的死代码。

于 2013-08-21T05:24:58.087 回答
3

对于简单的布尔表达式|有时||. 有时您希望对表达式进行统一评估(例如++在索引值中有 a 时。

你不能意外地“混合”布尔|和按位|,因为你不能混合布尔和整数操作数。但是你可以(当然)不小心|在你打算使用的地方使用||. 谢天谢地,它不是 C,您可能会不小心在其中使用=而不是==.

于 2013-08-21T05:25:24.210 回答
2

如果你使用,

  if(true || /*someStatementHere*/)

那么整个if块将是真的,因为第一个条件是真的,所以它不必检查另一个

简单地说,如果第一个条件在短路运算符的情况下给出结果,则不会评估右侧操作数

于 2013-08-21T05:19:35.453 回答
1

我不知道为什么所有人都说按位只能对布尔操作数进行操作。我告诉你按位运算符适用于操作数的类型,并根据操作数返回相同类型的值。只是为了理解,将按位运算符视为可以添加 2 个数字的数学“+”运算符。在按位的情况下相同。

if(10 | 11) 不会给出编译错误。如果结果为 0,则为假,否则为真。

BITWISE OPERATORS 不会短路,因为按位总是需要 2 个操作数才能执行。小心按位使用 OPERANDS 而不是 Boolean_CONDITIONs

句法:

   for bitwise :  (operand_1) bitwise_operator (operand_2)
                 for example: ( 2 ) | ( 3 )

   for LOGICAL :  (Boolean_condition_1) LOGICAL_operator (Boolean_condition_2)
                 for example: ( true ) || ( false )
于 2020-10-27T10:22:23.940 回答