Performance Tips: Java without a JIT

Comparisons

We mentioned in the previous section that comparison with zero is slightly more efficient than comparisons with an arbitrary number.

Testing for multiple negative values

I would advise caution with this optimisation as the benefit is slight and it comes at the clear expense of readability. Nonetheless there is a slight gain possible in the fairly common case of comparing multiple values for negativity:

public void drawRectangle(int x0, int y0, int w, int h) {
  if (x0 < 0 || y0 < 0 || w < 0 || h < 0) {
    return;
  }
  // ...
}

If you are comparing more than two values, then the following version compiles to fewer bytecodes:

public void drawRectangle(int x0, int y0, int w, int h) {
  if ((x0 | y0 | w | h) < 0) {
    return;
  }
  // ...
}

If at this point you're wondering what the feck is going on, you'll not be alone. To understand this code you need a little knowledge about the way negative numbers are stored, and about how the binary OR operation works. Basically, for an integer to be classed as negative to the JM, it has to have its top bit (31) set. The OR operation means that if any of the variables has its top bit set (i.e. is negative) then the result of the OR operation will have its top bit set. In other words, the the expression X | Y will be negative if either X or Y is negative. It's yucky but it works. Incidentally, it also works for the case of AND.

In case you're thinking you'll just forget about this, the bad news is that this optimisation is used in quite a few places in the JDK source code. So if you need your team to understand the JDK source, it is worth being aware of this optimisation even if you choose to ban it in production...

All editorial content copyright (c) Neil Coffey 2007. All rights reserved.