Math.floor(x) MUCH slower then (int)x

2 replies [Last post]
chaose
Offline
Joined: 2006-07-04

Hello Everyone,

today we stumbled upon a huge performance leak while optimizing a raycasting algorithm. Much to our surprise, the Math.floor() method took almost half of the calculation time: 3 floor operations took the same amount of time as one trilinear interpolation. Since we could not belive that the floor-method could produce such a enourmous overhead, we wrote a small test program that reproduces the behavuior (tested in a 64bit and a 32bit Java environment).

The test program adds 5000000 floored/casted random double numbers. Here the reproducable results:

Casting ... Result = 10001538 (31 ms)
Rounding ... Result = 10001538 (344 ms)

The numbers differ that much that we are still unsure if we overlooked something stupid. Anyhow, the original raycasting algorithm runs twice as fast with casting ;)

Best Greetings,
ChaosE

mthornton
Offline
Joined: 2003-06-10

The int cast and floor don't produce the same result for negative numbers. The cast is much more common and so it is not surprising that more effort has been expended in optimising its calculation.

chaose
Offline
Joined: 2006-07-04

For those who want to run the small test program:

[code]package roundtest;

public class RoundTest {

/** Why is casting so much faster then rounding ? */
public static void main(String[] args) {
int SOMETHING_BIG = 5000000;
long start;
int sum;

double[] numbers = new double[SOMETHING_BIG];
for (int i=0; i numbers[i] = Math.random()*5;
}

System.out.print("Casting ... ");
start = System.currentTimeMillis();
sum = 0;
for (int i=0; i sum += (int)(numbers[i]);
}
System.out.println("Result = "+sum+ " ("+(System.currentTimeMillis()-start)+" ms)");

System.out.print("Rounding ... ");
start = System.currentTimeMillis();
sum = 0;
for (int i=0; i sum += Math.floor(numbers[i]);
}
System.out.println("Result = "+sum+ " ("+(System.currentTimeMillis()-start)+" ms)");

}

}
[/code]