I was looking through code in Guava https://github.com/google/guava and I see a lot of cool optimizations.
I was wondering if using & over && is an optimization and if it is, why is it? Could it be a style choice?
We are squaring an int b in the IntMath.checkedPow function. We want to check that b * b does not overflow:
checkNoOverflow(-FLOOR_SQRT_MAX_INT <= b & b <= FLOOR_SQRT_MAX_INT);
b *= b;
In this example, why was & used over &&?
Edit: Matt is correct. I compiled this Java code in Java 8:
public static boolean and (boolean a, boolean b){
return a && b;
}
public static boolean andBit (boolean a, boolean b){
return a & b;
}
I looked at the Byte code using Intellij. I see that we are using branching in the "and" function because we have IFEQ and GOTO.
// access flags 0x9
public static and(ZZ)Z
L0
LINENUMBER 8 L0
ILOAD 0
IFEQ L1
ILOAD 1
IFEQ L1
ICONST_1
GOTO L2
L1
FRAME SAME
ICONST_0
L2
FRAME SAME1 I
IRETURN
L3
LOCALVARIABLE a Z L0 L3 0
LOCALVARIABLE b Z L0 L3 1
MAXSTACK = 1
MAXLOCALS = 2
// access flags 0x9
public static andBit(ZZ)Z
L0
LINENUMBER 12 L0
ILOAD 0
ILOAD 1
IAND
IRETURN
L1
LOCALVARIABLE a Z L0 L1 0
LOCALVARIABLE b Z L0 L1 1
MAXSTACK = 2
MAXLOCALS = 2
}
To answer the question, & is faster if the cost of evaluating an extra <= is faster than branching.
Erwin's comment made me look closer at the actual while loop. b *=b is in a while loop which may repeat a lot. However, b can only be negative in the first loop because when we pass b *= b: b will be positive from then on.
In 1947, the British viceroy announced that after 200 years of British rule, India would gain independence and be partitioned into Hindu India and Muslim Pakistan.
The objective of the mission was to arrange for an orderly transfer to independence. In early 1946, new elections were held in India. Muslim voters could choose between a united Indian State or partition.
Seventy-five years ago, Sir Cyril Radcliffe, a British lawyer, was commissioned to draw the borders that would divide British-ruled India into two new, independent nations: Hindu-majority India and mainly Muslim Pakistan.
When the British left, they partitioned India, creating the separate countries of India and Pakistan to accommodate religious differences between Pakistan, which has a majority Muslim population, and India, which is primarily Hindu.
Since conditional branches are somewhat expensive, but comparing the values of integers is very fast, the fastest way to implement that expression in machine instructions would evaluate both sub-expressions and would not include a conditional branch.
The way it is written in your code snippet does reflect the best way to implement it. We usually expect the compiler to figure stuff like this out by itself, but maybe they tested and found that it did not...
Or maybe the developer just wrote it the faster way because the alternative would be to write it in a way that might be slower -- and there's certainly no good reason to do that!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With