I am trying to test the speed of autoboxing and unboxing in Java, but when I try to compare it against an empty loop on a primitive, I noticed one curious thing. This snippet:
for (int j = 0; j < 10; j++) {
long t = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++)
;
t = System.currentTimeMillis() - t;
System.out.print(t + " ");
}
Every time I run this, it returns the same result:
6 7 0 0 0 0 0 0 0 0
Why does the first two loops always take some time, then the rest just seem to be skipped by the system?
In this answer to this post, it is said that Just-In-Time compilation will be able to optimize this away. But if so, why the first two loops still took some time?
n: Number of times the loop is to be executed. In this case, in each iteration of i, inner loop is executed 'n' times. The time complexity of a loop is equal to the number of times the innermost statement is to be executed. On the first iteration of i=0, the inner loop executes 0 times.
For creating a loop that runs infinitely, we can use empty statements. However, if we use break statements inside the body of the loop, then the loop can terminate. If we want to create a for-loop or while loop that has an empty body, we can use an empty statement.
The procedure takes 10 to 20 minutes. You'll be able to go home afterward as soon as you feel up to it.
However, in a for loop, any of the three fields can be left blank. If you leave init blank, then there is no initialization phase. You just start with the cond. If you leave update blank, then there is no update phase.
JIT triggers AFTER a certain piece of code has been executed many times.
The HotSpot JVM will try to identify "hot spots" in your code. Hot spots are pieces of your code that are executed many many times. To do this, the JVM will "count" the executions of various instructions, and when it determines a certain piece is executed frequently, it will trigger the JIT. (this is an approximation, but it's easy to understand explained this way).
The JIT (Just-In-Time) takes that piece of code, and tries to make it faster.
The techniques used by the JIT to make your code run faster are a lot, but the one that most commonly creates confusion are :
So, the proper answer to your question is that an empty loop, after being JITed, takes no time to execute .. most probably is not there anymore.
Again, there are many other optimizations, but in my experience these are among those that have created most headaches.
Moreover, JIT is being improved in any new version of Java, and sometimes it is even a bit different depending on the platform (since it is to some extent platform specific). Optimizations done by the JIT are difficult to understand, because you cannot usually find them using javap and inspecting bytecode, even if in recent versions of Java some of these optimizations have been moved to the compiler directly (for example, since Java 6 the compiler is able to detect and warn about unused local variables and private methods).
If you are writing some loops to test something, it is usually good practice to have the loop inside a method, call the method a few times BEFORE timing it, to give it a "speed up" round, and then perform the timed loop.
This usually triggers the JIT in a simple program like yours, even if there is no guarantee that it will actually trigger (or that it even exists on a certain platform).
If you want to get paranoid about JIT or non JIT timing (I did): make a first round, timing each execution of the loop, and wait until the timing stabilize (for example, difference from the average less than 10%), then start with your "real" timing.
The JIT doesn't kick in on a chunk of code until it determines that there is some benefit to doing so. That means the first few passes through some code won't be JITed.
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