49

I'd like to know some cases in Java (or more generally: in programming) when it is preferred in boolean expressions to use the unconditional AND (&) instead of the conditional version (&&).

I know how they work, but I cannot think about a case when use the single & is worth it.

Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131
Luigi Massa Gallerano
  • 2,347
  • 4
  • 23
  • 25

11 Answers11

61

I have found cases in real life where both sides of the expression were really cheap, so it shaved off a nanosecond or two to avoid the branch and to use the unconditional & instead of &&. (These were extremely high-performance math utilities, though; I would almost never use this in other code, and I wouldn't have done it anyway without exhaustive benchmarking to prove it was better.)

(To give specific examples, x > 0 is going to be super cheap and side-effect-free. Why bother risking a branch misprediction to avoid a test that's going to be so cheap anyway? Sure, since it's a boolean the end result is going to be used in a branch anyway, but if (x >= 0 && x <= 10) involves two branches, and if (x >= 0 & x <= 10) involves only one.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Out of curiosity, how can 2 boolean evaluations + an AND be quicker than one boolean evaluation? – assylias Jul 10 '12 at 11:23
  • 23
    `&&` involves a branch, when it decides whether or not to evaluate the second condition. Mispredicted branches can be highly expensive on modern CPUs. `&` avoids that branch. – Louis Wasserman Jul 10 '12 at 11:26
  • 7
    @assylias: See also [Why is processing a sorted array faster than an unsorted array?](http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array) – BlueRaja - Danny Pflughoeft Jul 10 '12 at 16:22
  • 25
    ...Of all my answers to get this many upvotes, I would _not_ have expected it to be this one. Readers, you should almost _never_ use `&` in actual code -- certainly not without at least an hour's worth of developing microbenchmarks for _each_ place you want to switch a `&&` to an `&`. I work on libraries that get used by thousands of programmers, so microoptimizations pay off in those situations, but almost nobody else should do these kinds of things. – Louis Wasserman Jul 10 '12 at 20:00
  • @LouisWasserman: if both sides of the expression is really simple, then the compiler should be able to inline it, and therefore, using & and && should produce the same bytecode after optimization, no? – Lie Ryan Jul 11 '12 at 03:18
  • Not really. Asking it to print the generated assembly does show differences, so I guess not? – Louis Wasserman Jul 11 '12 at 09:52
  • 1
    (In any event, the compiler will generate different bytecode for `i >= 0 && i <= 10` and `i >= 0 & i <= 10`. It's not a question of inlining, it's a question of semantics. – Louis Wasserman Jul 11 '12 at 10:32
  • 2
    @LouisWasserman in your example both would be the same as there are no visible side effects, so the compiler would be free to optimize it. The only reason the compiler produces different bytecode is that javac does almost no optimization - the JIT compiler takes care of optimizing the native instructions. – josefx Jul 11 '12 at 20:06
  • (To be clear, there _are_ differences in the assembly emitted by the JIT, at least in the cases I've studied; you can test it yourself using appropriate command line options.) – Louis Wasserman Jul 11 '12 at 20:29
  • 2
    Yep Louis is right. The JIT really isn't capable of optimizing `if (val >= 0xcafe && val < 0xdead)` sensibly - gcc does though. – Voo Jul 12 '12 at 18:50
  • I mean, I wouldn't be surprised at all if that optimization did appear in the future, but it's not there in the versions of Java that I've been testing against. – Louis Wasserman Jul 12 '12 at 18:57
  • That's pretty irrelevant here, but the optimal evaluation of the above conjunction is "unsigned less or equal" (JBE in i86 assembly). I'd bet that's what gets done for array index checks. – maaartinus Sep 08 '13 at 12:47
20

The only difference is that && and || stop the evaluation as soon as it is known. So for example:

if (a != null && a.get() != null)

works well with &&, but with & you could get a NullPointerException if a is null.

The only case I can think about where you want to use & is if the second operand has a side effect, for example (probably not the best example but you get the point):

public static void main(String[] args) {
    int i = 1;
    if (i == 0 & ++i != 2) {
    }
    System.out.println(i); //2
    i = 1;
    if (i == 0 && ++i != 2) {
    }
    System.out.println(i); //1
}

However, this looks like smelly code to me (in both cases).

assylias
  • 321,522
  • 82
  • 660
  • 783
  • Oh man, that is some smelly code right there. If I found this in some massive class I needed to debug, it would take me *hours* to spot. – dimo414 Aug 27 '13 at 02:49
15

The && allows the jvm to do short circuit evaluation. That is, if the first argument is false, then it doesn't need to bother checking the second argument.

A single & will run both sides regardless.

So, as a contrived example, you might have:

if (account.isAllowed() & logAccountAndCheckFlag(account))
    // Do something

In that example, you might always want to log the fact that the owner of the account attempted to do something.

I don't think I have ever used a single & in commercial programming though.

Taskmaster
  • 966
  • 8
  • 16
11

Wikipedia has nicely described the Short Circuit Evaluation

Where do you prefer non short-circuit operators ?

From the same link:

  • Untested second condition leads to unperformed side effect
  • Code efficiency

Short-circuiting can lead to errors in branch prediction on modern processors, and dramatically reduce performance (a notable example is highly optimized ray with axis aligned box intersection code in ray tracing)[clarification needed]. Some compilers can detect such cases and emit faster code, but it is not always possible due to possible violations of the C standard. Highly optimized code should use other ways for doing this (like manual usage of assembly code)

Santosh
  • 17,667
  • 4
  • 54
  • 79
  • Honestly, the branch prediction issue is hogwash. Any compiler worth its salt will be able to find a branchfree representation even for the short-circuit path, unless the second expression cannot be proven not to have side-effects, which generally involves non-inlineable code. Programmers worrying about the branch predictor before looking at inlining are doing something wrong. – Simon Richter Jul 11 '12 at 07:44
  • True to a large extent, especially for modern day compilers. – Santosh Jul 11 '12 at 10:23
7

If there are side effects that must happen, but that's a little ugly.

The bitwise AND (&) is mostly useful for just that - bitwise math.

harold
  • 61,398
  • 6
  • 86
  • 164
7

Input validation is one possible case. You typically want to report all the errors in a form to the user in a single pass instead of stopping after the first one and forcing them to click submit repeatedly and only get a single error each time:

public boolean validateField(string userInput, string paramName) {
   bool valid;
   //do validation 

   if (valid) {
       //updates UI to remove error indicator (if present)
       reportValid(paramName);   
   } else {
       //updates UI to indicate a problem (color change, error icon, etc) 
       reportInvalid(paramName);  
   }      
}

public boolean validateAllInput(...) {

   boolean valid = true;
   valid = valid & validateField(userInput1, paramName1);
   valid = valid & validateField(userInput2, paramName2);
   valid = valid & validateField(userInput3, paramName3);
   valid = valid & validateField(userInput4, paramName4);
   valid = valid & validateField(userInput5, paramName5);

   return valid;
}

public void onSubmit() {

   if (validateAllInput(...)) {
       //go to next page of wizard, update database, etc
       processUserInput(userInput1, userInput2, ... );
   } 

}

public void onInput1Changed() {
   validateField(input1.Text, paramName1);
}


public void onInput2Changed() {
   validateField(input2.Text, paramName2);
}

...

Granted, you could trivially avoid the need for short circuit evaluation in validateAllInput() by refactoring the if (valid) { reportValid() ... logic outside of validateField(); but then you'd need to call the extracted code every time validateField() was called; at a minimum adding 10 extra lines for method calls. As always it's a case of which tradeoff's work best for you.

  • But using `&&` here is so much better. Otherwise you have to check every parameter pointlessly if the first one isn't valid. – OrangeDog Jul 10 '12 at 16:56
  • This is really a subset of the side-effects case listed above but it's a case where side effects might very well be tolerable programming. – Loren Pechtel Jul 10 '12 at 17:06
  • 2
    @OrangeDog If I fill out a form with N errors and click submit I'd prefer to be informed that I need to fix X, Y, and Z. It's much more user friendly than: clicking submit, getting an error about X, fixing it, clicking submit again, getting an error about Y.... – Dan Is Fiddling By Firelight Jul 10 '12 at 17:39
  • @LorenPechtel Taskmaster and harold's answers both implied it was something you could do but shouldn't. This is a case where IMO using & and taking advantage of side effects is the better implementation. – Dan Is Fiddling By Firelight Jul 10 '12 at 17:41
  • Oh right, I hadn't spotted you were giving feedback for all of them – OrangeDog Jul 10 '12 at 18:04
  • @DanNeely: although nowadays, it is someetimes much more preferable nowadays to get instant feedback, so you know the form is valid even without having to click submit. – Lie Ryan Jul 11 '12 at 03:22
  • Cute trick but for everyones sake don't use it, just reverse the order and use && instead, you sacrifice nothing and the next person is much more likely to get it. – Bill K Jul 11 '12 at 03:29
  • @LieRyan Depends what you're programming to an extent. eg in a webpage doing instant validation in the page via javascript; for java running on the server in most cases there's not any point in ajaxing per field validation instead of just wiring it to the submit button (uniqueness requirements for new usernames being one of the few exceptions). – Dan Is Fiddling By Firelight Jul 11 '12 at 13:13
  • @BillK maybe. I find shortName operator longName much easier to read than longName operator shortName; especially in repetitive constructs when shortName is fixed and longName varies (especially when longName varies in length instead of just incrementing). – Dan Is Fiddling By Firelight Jul 11 '12 at 13:17
  • Doesn't matter so much what you find margionallly easier to read (at virtually no cost), someone will waste hours some day because of your use of an unconventional construct... Assuming this isn't a personal project in which case why use java? Many languages have lots of "easier to read" (for the author) constructs, the advantage of java is that it is typically easier for someone else to read. – Bill K Jul 11 '12 at 13:44
6

If the expression are trivial, you may get a micro-optimisation by using & or | in that you are preventing a branch. ie.

if(a && b) { }
if(!(a || b)) { }

is the same as

if (a) if (b) { }
if (!a) if (!b) { }

which has two places a branch can occur.

However using an unconditional & or |, there can be only one branch.

Whetehr this helps or not is highly dependant on what the code is doing.

If you use this, I sugegst commenting it to make it very clear why it has been done.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
5

There isn't any specific use of single & but you can consider the following situation.

if (x > 0 & someMethod(...))
{
  // code...
}

Consider that someMethod() is doing some operation which will modify instance variables or do something which will impact behavior later in processing.

So in this case if you use && operator and the first condition fails it will never go in someMethod(). In this case single & operator will suffice.

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Pranav Kevadiya
  • 519
  • 1
  • 6
  • 17
3

Because & is a bit-wise operator, you can do up to 32-checks in a single operation concurrently. This can become a significant speed gain for this very specific use cases. If you need to check a large number of conditions, and do it often and the cost of boxing/unboxing the conditions are amortized by the number of checks, or if you store your data on-disk and on-RAM in that format (it is more space efficient to store 32 conditions in a single bitmask), the & operator can give a huge speed benefit over a series of 32 individual &&. For example if you want to select all units that can move, is an infantry, has weapon upgrade, and is controlled by player 3, you can do:

int MASK = CAN_MOVE | INFANTRY | CAN_ATTACK | HAS_WEAPON_UPGRADE | PLAYER_3;
for (Unit u in allunits) {
    if (u.mask & MASK == MASK) {
        ...;
    }
}

See my other answers on a related question for more on the topic.

Community
  • 1
  • 1
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
1

The only benefit I can think of is when you need to invoke a method or execute a code, no matter the first expression is evaluated to true or false:

public boolean update()
{
    // do whatever you want here
    return true;
}

// ...

if(x == y & update()){ /* ... */}

Although you can do this without &:

if(x == y){/* ... */}
update();
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 1
    The first code is quite dangerous. If I saw this in a project I would assume the programmer made an error here, and correct it, thus removing the unconditional side-effect inadvertently. – Konrad Rudolph Jul 11 '12 at 08:04
1

Short-circuiting can lead to errors in branch prediction on modern processors, and dramatically reduce performance (a notable example is highly optimized ray with axis aligned box intersection code in ray tracing)[clarification needed].

anil patel
  • 21
  • 1