3

In the following code:

long startingTime = System.nanoTime();
int max = (int) Math.pow(2, 19);
for(int i = 0; i < max; ){
    i++;
}
long timePass = System.nanoTime() - startingTime;
System.out.println("Time pass " + timePass / 1000000F);

I am trying to calculate how much time it take to perform simple actions on my machine.

All the calculations up to the power of 19 increase the time it takes to run this code, but when I went above 19(up to max int value 31) I was amazed to discover that it have no effect on the time it takes. It always shows 5 milliseconds on my machine!!!

How can this be?

jonsca
  • 10,218
  • 26
  • 54
  • 62
Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
  • Math.pow is not only expensive but can have rounding errors. Try `1 << 19` which is the same as `(int) Math.pow(2, 19)` except more efficient. – Peter Lawrey Jul 09 '12 at 08:29

3 Answers3

12

You have just witnessed HotSpot optimizing your entire loop to oblivion. It's smart. You need to do some real action inside the loop. I recommend introducing an int accumulator var and doing some bitwise operations on it, and finally printing the result to ensure it's needed after the loop.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
2

On the HotSpot JVM, -XX:CompileThreshold=10000 by default. This means a loop which iterates 10K times can trigger the whole method to be optimised. In your case you are timing how long it take to detect and compile (in the background) your method.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 2
    It is fun to notice also that, if we can assume OP is running the whole thing in a single method. HotSpot actually replaces the method's code in the middle of its execution, transfering the complete state from the interpreted to the compiled version! – Marko Topolnik Jul 09 '12 at 08:47
  • Something JRocket doesn't do btw. This means that your first main() will never be optimised in JRocket. – Peter Lawrey Jul 09 '12 at 08:51
  • 1
    @MarkoTopolnik: when I read up on some HotSpot teachniques I came accross "deoptimization" which actually does the reverse! That's even more fun. (That's necessary if a assumption made about the code later gets invalidated, such as the VM "knowing" that there's only a single class involved and later a second class in the same hierarchy gets loaded). – Joachim Sauer Jul 09 '12 at 10:07
  • I believe it will also deoptimise if it assume a condition is always false and it later becomes true (visa-versa) e.g. turning assertions on. – Peter Lawrey Jul 09 '12 at 10:51
0

use another System.nanoTime() in the loop. no one can optimize this.

for(int i = 0; i < max; ){
i++;
dummy+=System.nanoTime();
}

dont forget to do:

System.out.println(dummy);

after the loop. ensures non-optimization

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97