I'm writing some code in Java where, at some point, the flow of the program is determined by whether two int variables, "a" and "b", are non-zero (note: a and b are never negative, and never within integer overflow range).

I can evaluate it with

```
if (a != 0 && b != 0) { /* Some code */ }

```

Or alternatively

```
if (a*b != 0) { /* Some code */ }

```

Because I expect that piece of code to run millions of times per run, I was wondering which one would be faster. I did the experiment by comparing them on a huge randomly generated array, and I was also curious to see how the sparsity of the array (fraction of data = 0) would affect the results:

```
long time;
final int len = 50000000;
int arbitrary = 0;
int[][] nums = new int[2][len];

for (double fraction = 0 ; fraction <= 0.9 ; fraction += 0.0078125) {
    for(int i = 0 ; i < 2 ; i++) {
        for(int j = 0 ; j < len ; j++) {
            double random = Math.random();

            if(random < fraction) nums[i][j] = 0;
            else nums[i][j] = (int) (random*15 + 1);
        }
    }

    time = System.currentTimeMillis();

    for(int i = 0 ; i < len ; i++) {
        if( /*insert nums[0][i]*nums[1][i]!=0 or nums[0][i]!=0 && nums[1][i]!=0*/ ) arbitrary++;
    }
    System.out.println(System.currentTimeMillis() - time);
}

```

And the results show that if you expect "a" or "b" to be equal to 0 more than ~3% of the time, `a*b != 0` is faster than `a!=0 && b!=0`:

[![Graphical graph of the results of a AND b non-zero](https://i.stack.imgur.com/POHYD.png)](https://i.stack.imgur.com/POHYD.png)

I'm curious to know why. Could anyone shed some light? Is it the compiler or is it at the hardware level?

**Edit:** *Out of curiosity...* now that I learned about branch prediction, I was wondering what the analog comparison would show for a **OR** b is non-zero:

[![Graph of a or b non-zero](https://i.stack.imgur.com/GpJoM.png)](https://i.stack.imgur.com/GpJoM.png)

We do see the same effect of branch prediction as expected, interestingly the graph is somewhat flipped along the X-axis.

### Update

1- I added `!(a==0 || b==0)` to the analysis to see what happens.

2- I also included `a != 0 || b != 0`, `(a+b) != 0` and `(a|b) != 0` out of curiosity, after learning about branch prediction. But they are not logically equivalent to the other expressions, because only a *OR* b needs to be non-zero to return true, so they are not meant to be compared for processing efficiency.

3- I also added the actual benchmark that I used for the analysis, which is just iterating an arbitrary int variable.

4- Some people were suggesting to include `a != 0 & b != 0` as opposed to `a != 0 && b != 0`, with the prediction that it would behave more closely to `a*b != 0` because we would remove the branch prediction effect. I didn't know that `&` could be used with boolean variables, I thought it was only used for binary operations with integers.

Note: In the context that I was considering all this, int overflow is not an issue, but that's definitely an important consideration in general contexts.

CPU: Intel Core i7-3610QM @ 2.3GHz

Java version: 1.8.0\_45  

Java(TM) SE Runtime Environment (build 1.8.0\_45-b14)  

Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)