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
(&
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.
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.)
Wikipedia has nicely described the Short Circuit Evaluation
Where do you prefer non short-circuit operators ?
From the same link:
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)
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.
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).
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.