Ok, I’ve put together the entire benchmark into a single class (see below). On Java 5 -server I get:
Float: 776 iterations / s
Double: 642 iterations / s
Fixed point: 1793 iterations / s
2.9308171, 2.8822784, 2.9308173801885786
With JRockit I get:
Float: 1572 iterations / s
Double: 1575 iterations / s
Fixed point: 1800 iterations / s
2.9308174, 2.8822784, 2.9308173801885786
Note the 2x speed improvement in the float and double benchmarks. I get the same scores for a similar C test compiled with GCC or Visual Studio.
It’s a VERY simple loop to optimize (fmul, fadd, jump in the assembler output from GCC), so it’s really surprising that Hotspot can’t optimize it properly. You’re more than welcome to try to tweak the code to make it run fast in Hotspot.
public class MathTest {
private static final float x = 0.7456f;
private static final float y = 0.97543f;
private static final int count = 100000;
private static float f1;
private static float f2;
private static double f3;
private static void run(String text, Runnable runnable) {
long time = System.currentTimeMillis();
while (System.currentTimeMillis() - time < 10000) {
runnable.run();
}
time = System.currentTimeMillis();
long count = 0;
while (System.currentTimeMillis() - time < 10000) {
runnable.run();
count++;
}
System.out.println(text + ": " + count * 1000L / (System.currentTimeMillis() - time) + " iterations / s");
}
public static void main(String[] args) {
run("Float", new Runnable() {
public void run() {
float a = x;
float b = y;
for (int i=0; i<count; i++) {
b = a * b + a;
}
f1 = b;
}
});
run("Double", new Runnable() {
public void run() {
double a = x;
double b = y;
for (int i=0; i<count; i++) {
b = a * b + a;
}
f3 = b;
}
});
run("Fixed point", new Runnable() {
public void run() {
int a = (int) (x * 65536.0f);
int b = (int) (y * 65536.0f);
for (int i=0; i<count; i++) {
b = (a >> 8) * (b >> 8) + a;
}
f2 = (float) b / 65536.0f;
}
});
System.out.println(f1 + ", " + f2 + ", " + f3);
}
}