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
?
max method is likely to be slower, but it also may return a different result if one of the arguments is NaN.
Using Math. Min in a loop is almost 4 times slower than before.
Since Math.max
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!
Variable 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.
Math.max(a,b)
can be very aggressivly/obviously optimized into a native instruction for the processor.
For the ternary, the simple transformation into processor instruction would be a compare+jump, especially the jump is costly.
To optimize the ternary into the JIT(Just in time compiler) must recognize that the code expresses a max and the native instruction is best.
The JIT might eventually recognize this but until that point it will be slower.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With