Why was & used over && in java when comparing two bools?

Eric Cherin :

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.

Matt Timmermans :

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!

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=457121&siteId=1
Recommended