I suspect this is a JVM warming effect. In particular, the JIT code is compiled at some point, and this distorts the time you see.
Put the entire batch in a loop and ignore the time until they stabilize. (But note that they will not be fully stabilized. Garbage is generated, and therefore the GC will have to be hit periodically. This can distort the timings at least a little. The best way to handle this is to run a huge number of iterations of the outer loop and calculate / display the average time.)
Another problem is that the JIT compiler on some versions of Java can optimize the omissions you are trying to verify:
You can understand that the creation and immediate removal of Long
objects could be optimized. (Thanks Louis!)
You can understand that loops do "busy work" ... and fully optimize them. (The value
not used after the completion of each cycle.)
FWIW, it is generally recommended to use Long.valueOf(long)
, rather than new Long(long)
, because the former can use an instance of cached Long
. However, in this case, we can predict that in all but the first few iterations of the loop, there will be no cache miss, so the recommendation will not help. In any case, this is likely to make the cycle in the question slower.
UPDATE
I conducted my own investigation and received the following:
import java.util.*; public class Main { public static void main(String[] args) { while (true) { test(); } } private static void test() { long start = System.currentTimeMillis(); long limit = 10000000;
which gave me the following result.
28 58 2220 99999990000000 40 58 2182 99999990000000 36 49 157 99999990000000 34 51 157 99999990000000 37 49 158 99999990000000 33 52 158 99999990000000 33 50 159 99999990000000 33 54 159 99999990000000 35 52 159 99999990000000 33 52 159 99999990000000 31 50 157 99999990000000 34 51 156 99999990000000 33 50 159 99999990000000
Note that the first two columns are pretty stable, but the third shows significant acceleration in the third iteration ... probably indicates that the JIT compiled.
Interestingly, before I separated the test into a separate method, I did not see acceleration in the third iteration. All numbers looked like the first two lines. And that seems to indicate that the JVM (which I'm using) will not JIT compile the method that is currently executing ... or something like that.
In any case, this shows (to me) that there should be a warming effect. If you donβt see the warm-up effect, your test does what prevents the JIT from compiling ... and therefore does not make sense for real applications.