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?

phuclv
  • 37,963
  • 15
  • 156
  • 475
kin3tik
  • 325
  • 1
  • 5
  • 13
  • 1
    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. – cHao Aug 21 '13 at 05:40
  • @cHao Yep, correct. Removed it just before I saw your comment anyway as it wasn't really that relevant to the actual question. – kin3tik Aug 21 '13 at 05:42
  • possible duplicate of [Reason for the exsistance of non-short-circuit logical operators](http://stackoverflow.com/questions/9264897/reason-for-the-exsistance-of-non-short-circuit-logical-operators) – fredoverflow Sep 08 '14 at 07:34
  • 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. – Agoston Horvath Apr 01 '17 at 17:02

9 Answers9

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.

Eamonn O'Brien-Strain
  • 3,352
  • 1
  • 23
  • 33
  • Ah, that is a good point I hadn't considered. But wouldn't relying on effects like this generally be considered a bad practise? – kin3tik Aug 21 '13 at 05:27
  • Yes, I added that point to the answer just before I saw your comment! It is indeed bad practise. – Eamonn O'Brien-Strain Aug 21 '13 at 05:29
  • With the added edits this seems like the best answer to my question (covering rhs side effects and occasional performance benefits). – kin3tik Aug 21 '13 at 06:12
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.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 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. – BeeOnRope Dec 10 '14 at 23:40
  • @BeeOnRope 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. – Peter Lawrey Dec 11 '14 at 10:40
  • 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 `|`. – BeeOnRope Dec 11 '14 at 20:28
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.

Community
  • 1
  • 1
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
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 :)

cHao
  • 84,970
  • 20
  • 145
  • 172
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 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. – Craig Taylor Nov 13 '17 at 20:09
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

jmj
  • 237,923
  • 42
  • 401
  • 438
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.

Farrukh Chishti
  • 7,652
  • 10
  • 36
  • 60
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 ==.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • `{ boolean b = false; if (b = true) { /*do stuff*/ } }` is actually allowed, and does stuff. Which kinda messes with your last sentence. :) – cHao Aug 21 '13 at 05:29
  • @cHao - 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`.) – Hot Licks Aug 21 '13 at 05:45
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

cHao
  • 84,970
  • 20
  • 145
  • 172
Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56
  • 1
    I understand the difference, my question is more focused on finding a benefit to using `|` when only dealing with booleans. – kin3tik Aug 21 '13 at 05:23
  • Only benefit you can get is, short circuit operator will not evaluate anothe condition – Prasad Kharkar Aug 21 '13 at 05:24
  • 2
    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 `||`? – cHao Aug 21 '13 at 05:44
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 )