短路与非短路运营商

时间:2013-08-21 05:16:24

标签: java

我理解下面的差异(至少对Java来说):

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

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

9 个答案:

答案 0 :(得分:9)

您可能想要使用非短路操作符的一个原因是,如果您某种程度上取决于函数的副作用。例如。

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

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

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

实际上,您几乎总是希望使用短路运营商。依赖于表达式中的副作用通常是糟糕的编程习惯。

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

答案 1 :(得分:8)

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

注意:这是一种微观优化,除非被多次调用,否则很少会发现差异。

答案 2 :(得分:5)

short-circuit,意味着如果没有必要,他们不评估右侧。 例如,如果&&左侧是假的,则无需评估右侧的一侧。换句话说,||如果保持原样,则无需评估右手侧。{/ p>

non-short总是评估双方。

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

非短的好处,可以在这里找到答案。Are there good uses for non-short-circuiting logical (boolean) operators in 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
          } 
      }

我们现在需要检查双方。

答案 3 :(得分:5)

  

我的问题更侧重于找到使用|的好处什么时候只处理布尔值

考虑以下案例

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

    // tell something to user.

}

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

答案 4 :(得分:4)

只有你不想使用非短路操作符的地方才是你想要执行第二个语句,这通常不应该是条件语句中的情况

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

答案 5 :(得分:2)

如果您使用,

  if(true || /*someStatementHere*/)

然后整个if块将为真,因为第一个条件为真所以它不需要检查另一个

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

答案 6 :(得分:2)

第三个陈述

if( 10 | 11 )       // bitwise operator

将创建编译错误。只有布尔值可以放在if语句中。

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

答案 7 :(得分:2)

对于简单的布尔表达式,| 有时||更快。有时你想要统一评估表达式(就像索引值中有++一样。

您不能意外地“混合”布尔|和按位|,因为您无法混合布尔和整数操作数。但是你可以(当然)意外地使用|来表示你想要使用||。只是感谢它不是C,你不小心使用=代替==

答案 8 :(得分:0)

我不知道为什么所有人都说按位运算只能对布尔操作数进行运算。 我告诉您按位运算符可对操作数类型进行操作,并返回与每个操作数相同的值类型。仅出于理解的目的,将按位运算符视为数学“ +”运算符,可以将两个数字相加。按位的情况也一样。

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

BITWISE运算符不会短路,因为按位运算总是需要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 )