Question

As we know some people say java JIT is faster then C++. I had some idea to utilize JIT and remove some instructions at runtime code.

Here is sample code i tried:

/**
 * Created by kadirbasol on 4/6/14.
 */
public class RemoveJump {
    public final boolean test;

    private static RemoveJump instance = new RemoveJump();

    public static final RemoveJump getInstance() {
        return instance;
    }

    private RemoveJump() {
        //set the test on the constructor once and
        //remove this if statement forever from testLoop
        test = false;
    }


    public final long getData() {
        return 1000000000;
    }

    public final void testLoop() {
        long l = System.currentTimeMillis();
        int ppp = 0;
        long count = System.currentTimeMillis();
        final long data = getData();
        //this loop should be removed from function because
        //RemoveJump set test to false and modified testLoop function
        for (int i = 0; i <  data ; i++) {
            if(test) {
                ppp++;
            }
            if(test) {
                ppp++;
            }
            if(test) {
                ppp++;
            }
            if(test) {
                ppp++;
            }
            if(test) {
                ppp++;
            }
        }
        long lastTime = System.currentTimeMillis() - l;
        System.out.println(lastTime);
        System.out.println(ppp);
    }

    public static void main(String[] args) {
        RemoveJump.getInstance().testLoop();
    }
}

there are 5 if statement on the code. Is it possible to remove these 5 check if statements at function ? The constructor will set final boolean variable once and remove the jump. Constructor will modify the testLoop function.

But the code i tried has no effect. JIT is not modifying code ? why ? if not , can we modify JVM function on the constructor? i heard about http://asm.ow2.org , asm java library for generating or modifying JVM.

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top