views:

90

answers:

4

I have the following simple program that multiplies two different floating point numbers many times. As you can see, one of the numbers is very small. When I calculate the time of executing both multiplications, I was surprised that the little number takes much longer than the other one. It seems that working with small doubles is slower... Does anyone know what is happening?

public static void main(String[] args) throws Exception
{
 long iterations = 10000000;
 double result;
 double number = 0.1D;
 double numberA = Double.MIN_VALUE;
 double numberB = 0.0008D;

 long startTime, endTime,elapsedTime;


 //Multiply numberA
 startTime = System.currentTimeMillis();

 for(int i=0; i < iterations; i++)
  result = number * numberA;

 endTime = System.currentTimeMillis();
 elapsedTime = endTime - startTime;

 System.out.println("Number A) Time elapsed: " + elapsedTime + " ms");

 //Multiply numberB
 startTime = System.currentTimeMillis();
 for(int i=0; i < iterations; i++)
  result = number * numberB;

 endTime = System.currentTimeMillis();
 elapsedTime = endTime - startTime;

 System.out.println("Number B) Time elapsed: " + elapsedTime + " ms");
}

Result:

Number A) Time elapsed: 3546 ms
Number B) Time elapsed: 110 ms

Platform Windows, Java 1.6.0_07

Thanks, Diego

+2  A: 

My guess is that the compiler replaced

number * numberB;

with its exact value, because number and numberB are both constant values that the compiler knows have not changed by that point. However, numberA is not a constant value (its value is platform-specific), and so you have to actually do the calculation every time. Try replacing Double.MIN_VALUE with its actual value, and see if they perform similarly.

Nick Lewis
Nop, I replaced it with 4.9E-324 and it get the same results... Thanks!!
Do it with 0.0000008 and start to increase the zeros before the 8.
kd304
Hmm, I also entirely missed the fact that you're multiplying epsilon by a number less than 1.. That almost certainly has something to do with it!
Nick Lewis
I mean draw a histogram based on logarithmic scaled test values.
kd304
I ran it in Ubuntu 8.04 and get:Number A) Time elapse : 44 msNumber B) Time elapse : 49 msThere is something strange with Windows JVM...
+3  A: 

When operating near the minimum representation of an IEEE 758 floating-point value, you are likely to get results that are "denormal". These are sometimes, though not always, processed more slowly. I suspect that the JVM is handling them specially somehow rather than relying on pure hardware support, leading to some performance degradation.

Tim Sylvester
A: 

It may be that you enter the range of "denormal" numbers (see IEEE754 format). Handling these numbers may require more time in the floating point unit.

Eric Bainville
I ran it in Ubuntu 8.04 and get: Number A) Time elapse : 44 ms Number B) Time elapse : 49 ms There is something strange with Windows JVM...
A: 

It seems to be an error in Windows JVM