I don't know about other guys but definitely I used System.currentTimeMillis() to calculate method execution time while doing performance analysis using junits.
This post will cover how things can go completely wrong with such kind of performance testing.
Before we deep dive into the issue let me put a code snippet to explain the issue in better manner:
As we can see in above code, system is calculating sum of numbers starting from zero to provided input number and returning the result. Also we are calculating execution time of method sum using System.currentTimeMillis().
Now by going through code we can say that total execution time calculation depends on for loop which executed 500000000 time and "sum = sum + (double)index" calculation.
Here our thinking can go wrong with respect to JIT compiler and reason to say that JIT compiler is too much smart.
Let us understand sample of how JIT optimization works:
1. As you can see in main method, we haven't used variable returned from ArithmeticProgression sum method.
2. So when JIT see such kind of code which doesn't mean anything to caller, it just run empty for loop without doing any calculation of "sum = sum + (double)index".
So our assumption of calculating execution time can go completely wrong with the case.
Bottom line is JIT compiler uses a lot of background algorithm to optimize our code while running.
Note:
1. JIT compiler optimization is highly platform dependent so you cannot expect same behaviour across different platform.
2. Scenario is hard to reproduce on local system eclipse as JIT works on compilationThreshold flag of JVM so JIT comes into picture only when compilation reaches over compilationThreshold value.
This post will cover how things can go completely wrong with such kind of performance testing.
Before we deep dive into the issue let me put a code snippet to explain the issue in better manner:
public class APSum {
public static void main(String[] args) {
long then = System.currentTimeMillis();
ArithmeticProgression.sum(500000000);
long now = System.currentTimeMillis();
System.out.println("Elapsed time: " + (now - then));
}
}
class ArithmeticProgression{
public static double sum(int i){
double sum=0;
for(int index=0; index<=i; index++){
sum = sum + (double)index;
}
return sum;
}
}
As we can see in above code, system is calculating sum of numbers starting from zero to provided input number and returning the result. Also we are calculating execution time of method sum using System.currentTimeMillis().
Now by going through code we can say that total execution time calculation depends on for loop which executed 500000000 time and "sum = sum + (double)index" calculation.
Here our thinking can go wrong with respect to JIT compiler and reason to say that JIT compiler is too much smart.
Let us understand sample of how JIT optimization works:
1. As you can see in main method, we haven't used variable returned from ArithmeticProgression sum method.
2. So when JIT see such kind of code which doesn't mean anything to caller, it just run empty for loop without doing any calculation of "sum = sum + (double)index".
So our assumption of calculating execution time can go completely wrong with the case.
Bottom line is JIT compiler uses a lot of background algorithm to optimize our code while running.
Note:
1. JIT compiler optimization is highly platform dependent so you cannot expect same behaviour across different platform.
2. Scenario is hard to reproduce on local system eclipse as JIT works on compilationThreshold flag of JVM so JIT comes into picture only when compilation reaches over compilationThreshold value.
No comments:
Post a Comment