In fact, JIT eliminates the check of test
field in the loop. Though it seems JIT is not smart enough to throw away the loop itself when the type of data
differs from the type of loop index i
:
0x000000000222f570: inc %ebx ; OopMap{rbp=Oop off=178}
;*goto
; - RemoveJump::testLoop@82 (line 28)
0x000000000222f572: test %eax,-0x20ff578(%rip) # 0x0000000000130000
;*iload
; - RemoveJump::testLoop@20 (line 28)
; {poll}
0x000000000222f578: movslq %ebx,%r10
0x000000000222f57b: cmp %r14,%r10
0x000000000222f57e: jl 0x000000000222f570
If you change getData()
to return int
, the optimization will work, and there will be no loop at all in the result assembly.
However your test case will not reveal the optimization effect, because the loop starts executing in the interpreter mode, gets compiled in the middle of execution (while being inside the loop), so even after the compilation the execution remains inside the loop. But if you invoke your testLoop()
several times, you'll see that the further invocations of the method will instantly print the result without going through the loop:
for (int i = 1; i <= 5; i++) {
System.out.println("Run #" + i);
RemoveJump.getInstance().testLoop();
}
Run #1
1897
0
Run #2
1895
0
Run #3
0
0
Run #4
0
0
Run #5
0
0