Short circuit vs non short circuit operators
Asked Answered
F

9

8

I understand the difference below (at least for Java):

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

But my question is, is there any reason to use the non-short-circuiting operator when you are dealing with boolean expressions? Is there some performance benefit or use that wouldn't be considered bad practise?

Foreandafter answered 21/8, 2013 at 5:16 Comment(4)
You wouldn't be able to accidentally use | as a bitwise operator; both operands would have to be either boolean or integral. And in a conditional expression, you're limited to boolean.Contaminant
@Contaminant Yep, correct. Removed it just before I saw your comment anyway as it wasn't really that relevant to the actual question.Foreandafter
possible duplicate of Reason for the exsistance of non-short-circuit logical operatorsDorthydortmund
In my experience, 98% of non-short circuiting operators is a typo, and the remaining 2% is bad design or dangerous code. It's just too easy to miss it. Think of the developer maintaining your code 5 years later.Nole
S
12

One reason you might want to use the non-short-circuiting operator is if you are somehow depending on side-effects of functions. For example.

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

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

If you don't care about whether the println is executed then you should use the short circuit operations as above. However, if you want both strings to be printed always (thus depending on side effects) then you need to use the non-short-circuit operator.

Practically speaking, you almost always want to use the short-circuit operators. Relying on side effects in expressions is usually bad programming practice.

One exception is in very low level or performance-sensitive code. The short-circuiting operators can be slightly slower because they cause branching in the program execution. Also using bitwise operators allows you to do 32 or 64 parallel boolean operations as a single integer operation, which is very fast.

Sacrilege answered 21/8, 2013 at 5:25 Comment(3)
Ah, that is a good point I hadn't considered. But wouldn't relying on effects like this generally be considered a bad practise?Foreandafter
Yes, I added that point to the answer just before I saw your comment! It is indeed bad practise.Localize
With the added edits this seems like the best answer to my question (covering rhs side effects and occasional performance benefits).Foreandafter
B
10

If your code is performance sensitive enough and the operations cheap enough, using the non-short circuit can be faster. This is because using || involves performing a branch, and a branch prediction miss can be very expensive. Where as the | performs a calculation and examining a variable can be much faster, avoiding a branch prediction miss.

Note: this is a micro-optimisation that you will rarely see a difference unless it is called many, many times.

Blondy answered 21/8, 2013 at 5:32 Comment(3)
In theory, the JIT can optimize either case to the other one where the RHS doesn't have side effects, so in the perfect world, performance wouldn't be a consideration (you could always use || for side-effect free comparisons). For example, Guava's LongMath class does use this optimization for the overflow check: (a ^ b) < 0 | (a ^ result) >= 0. I haven't checked whether Hotspot is yet smart enough to actually compile the same code for both cases. It's like how a ternary operator may imply branch free code versus if/else, but a good compiler generates the same code in both cases.Basic
@Basic In many cases, the JIT is smart enough to use Conditional Move assembly instruction. e.g. this means the max/min a > b ? a : b expression doesn't need a branch.Blondy
Indeed - my comment was more about how optimization sometimes renders performance advice obsolete. In particular, with gcc without optimization, if/else always generates branches, and the ternary operator generates CMOV (where possible, e.g., the choices are primitives). Given that, you might start recommending that ?: is used when the branches are unpredictable since the compiler treats them differently. However, the moment you turn on optimization, the difference disappears: both are compiled to branchless code. I suspect a similar equivalence occurs for || and |.Basic
A
6

short-circuit, meaning they don't evaluate the right hand side if it that doesn't necessary. As an example if && left hand side is false no need to evaluate right hand side one. In other way || if left is true no need to evaluate right hand side one.

non-short evaluvate both side always.

Then obviously there is a benefit with short-circuit operators.

And benefit of non-short, can find an answer here.Are there good uses for non-short-circuiting logical (boolean) operators in Java/Scala?

Consider this example too

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

we need to check both side now.

Alcoholic answered 21/8, 2013 at 5:19 Comment(2)
I understand the difference, my question is more focused on finding a benefit to using | when only dealing with booleans.Foreandafter
@Foreandafter I added more info to my answerAlcoholic
P
6

my question is more focused on finding a benefit to using | when only dealing with booleans

Consider the following case

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

    // tell something to user.

}

In this case | needed because I have to increase the attempt count too :)

Polygnotus answered 21/8, 2013 at 5:27 Comment(1)
This is a (very) late comment but I'd advise against using a | in this manner. It's not intuitive and ideally the loginAttempts increment would be moved out of the conditional if it must always be performed.Aguedaaguero
T
5

only place where you shouldn't use non short circuit operator is when you want second statement to be executed, which shouldn't be case in conditional statements generally

No, there is no performance with non short circuit, But there is absolutely benefit with short circuit

Thissa answered 21/8, 2013 at 5:18 Comment(0)
S
3

The third statement

if( 10 | 11 )       // bitwise operator

will create a compilation error. Only boolean values can be put inside an if statement.

If you are using an IDE like Eclipse, it will automatically show the second expression i.e. after || as dead code for short-circuit boolean operator.

Starry answered 21/8, 2013 at 5:24 Comment(1)
You are right. I will remove that line from the question as it isn't really relevant.Foreandafter
A
3

For simple Boolean expressions | is sometimes faster than ||. And sometimes you WANT expressions to be evaluated uniformly (as when there's a ++ in an index value.

You can't accidentally "mix" Boolean | and bitwise | since you can't mix Boolean and integer operands. But you can (of course) accidentally use | where you meant to use ||. Just be thankful it's not C, where you can accidentally use = instead of ==.

Agrology answered 21/8, 2013 at 5:25 Comment(2)
{ boolean b = false; if (b = true) { /*do stuff*/ } } is actually allowed, and does stuff. Which kinda messes with your last sentence. :)Contaminant
@Contaminant - Yes, but you can't say if (intVar1 = intVar2) and get it past the compiler in Java. C will happily accept it, however. (And your example is one reason why one should avoid expressions like boolValue == true (or false) vs simply boolValue or !boolValue.)Agrology
F
2

If you use,

  if(true || /*someStatementHere*/)

then the whole if block will be true because first condition is true so it does'nt have to check for the other

Simply saying, right hand side operand does not gets evaluated if the first condition gives the result in case of short circuit operators

Foxy answered 21/8, 2013 at 5:19 Comment(3)
I understand the difference, my question is more focused on finding a benefit to using | when only dealing with booleans.Foreandafter
Only benefit you can get is, short circuit operator will not evaluate anothe conditionFoxy
The question you're answering is kinda the opposite of the question being asked. We already know that || short circuits. The question is, is there ever a good reason to prefer | over ||?Contaminant
M
1

I dont know why all are saying bitwise can operates on boolean operands only. I am telling you bitwise operator works on type of operands and return the same type of value as per operands. Just for the understanding think bitwise operator as mathematical '+' operator which can add 2 numbers. same in case of bitwise.

if(10 | 11) will not give compilation error. if it results into 0 then it will be false else gives true.

BITWISE OPERATORS are not short circuited because bitwise always needs 2 operands to get executes . Be Careful bitwise uses OPERANDS not Boolean_CONDITIONs

SYNTAX:

   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 )
Morley answered 27/10, 2020 at 10:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.