kamil09875 kamil09875 - 4 months ago 7
Java Question

Why does inlining Math.max give over 200x slower code?

I've recently started benchmarking some Java code in order to get the best performance results for my program and noticed some strange thing. Namely, I've benchmarked the following methods:

private static final int n = 10000;

public static void test0(){
int m = 0;

for(int i = 0; i < n; ++i){
m = Math.max(i, m);
}
}

public static void test1(){
int m = 0;

for(int i = 0; i < n; ++i){
m = ((i >= m) ? i : m);
}
}


and got those results:

| Test 0 | Test 1 |
----------+-----------------+-----------------+-
Average: | 51,77 ns | 13956,63 ns |
Best: | 0,00 ns | 6514,00 ns |
Worst: | 25,45 ms | 60,50 ms |
Tries: | 16971233 | 16971233 |


After searching over SO (i.e. Is Math.max(a,b) or (a>b)?a:b faster in Java?) it was certain for me that
test1
shouldn't be so much slower.

These methods were tested randomly on 8 threads in 30 seconds and every benchmark I run seems similar.
I use
jdk1.8.0_45
.

So, why is
test1
over 200 times slower than
test0
?

Answer

Since Math.abs is a static function, the compiler * may figure out* that the code does nothing at all and simply optimizes the execution by not executing it!

m being local to the function, assigning it does not help as it is never read.

You need to make sure that the execution somehow modifies something so it is not aggressively optimized by the compiler.

For instance, you can can simply print the value of m at the end of the test or make m a class variable that can be accessed later or even sum the result as I originally suggested in the comment.