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 snippe
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.
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.