views:

339

answers:

2

Does the Java compiler remove multiplications by 1, when talking about BigDecimal?

I'm standing in something similar to this:

BigDecimal bd = getBigDecimal();//get arbitrary bigDecimal, could be anyone.

bd = bd.multiply(new BigDecimal(getOneTwoOrThree());

Where the getOneTwoOrThree method is declared as:

/* 
 * Always returns Integers 1, 2 or 3.
 */
 Integer getOneTwoOrThree(){
     //some code
 }

So, basically.

if getOneTwoOrThree() returns 1, will the compiler perform the multiplication? Or will it nop the instruction?
This is somewhat of an existential doubt, but I guess that I'm at some level early - optimizing.

+4  A: 

No. BigDecimal is a library class (it's not even in java.lang), so the compiler treats it as any other class.

BigDecimal could special-case this internally, but apparently doesn't.

(Edit: I should add that it's possible that the JIT compiler could work some magic, but I would have to do some tests to be sure.)

I would only suggest that you change your code to use BigDecimal.valueOf(), because 1, 2, and 3 are some of the special cases which are cached internally by BigDecimal.

bd = bd.multiply(BigDecimal.valueOf(getOneTwoOrThree());
Michael Myers
I think there's too much code here to inline or anything. I'd be very surprised if the JIT could do much with this. However, in this implementation, multiplying by one is inherently cheaper than multiplying by a number with lots of digits (more digits, more iterations of a loop).
erickson
You're probably right on the JIT. I was just noting that if the BigDecimals are small enough that their product fits into a long, the code path is significantly shorter. Unfortunately, multiplying a huge number by 1 triggers the hard case.
Michael Myers
A: 

If your function isn't deterministic, it cannot be optimized at compile-time anyway.

Pierre Gardin