Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java optimize away a field that's just serving as a return value?

Why I'm asking:

I wanted to know it there is any optimization going on at the compiler side that would make one or the other method to return preferable. Since I have read this post that python does not optimize the method to run faster.

The example:

I've declared 2 methods that deliver the same value. But barA returns it via an internal field declaration.

public class Foo {
    public int barA(){
        int a = 1;
        return a;
    }

    public int barB(){
        return 1;
    }
}

The tests:

public class TestFoo {
    Foo foo = new Foo();
    Method methodA = foo.getClass().getMethod("barA");
    Method methodB = foo.getClass().getMethod("barB");


    public TestFoo() throws NoSuchMethodException {
    }


    @Test
    public void methodA() throws Exception {
        assertTrue(Integer.TYPE.equals(methodA.getReturnType()));
    }

    @Test
    public void methodB() throws Exception {
        assertTrue(Integer.TYPE.equals(methodB.getReturnType()));
    }
    @Test
    public void equalsSame() throws Exception{
        assertEquals(foo.barA(), foo.barB());
    }
}

The results:

The tests showed that I'm in fact dealing with the same value and return type in both methods.

Disclaimer: This picture is not meant to highlight the stop watch, junit runs for each method, as it's in no way linked to the compiler optimization I'm asking about.

The tests

The question:

Does Java actually try to optimize away "useless" field declarations in order to execute faster?

I was not able to find a question addressing this.

Using:

  • jdk 1.8.0_121
  • junit 4.10
like image 922
blkpingu Avatar asked Oct 28 '25 04:10

blkpingu


1 Answers

If we take the example:

class Main  {
    int foo() {
        int i = 0;
        return i;
    }

    int bar() {
        return 0;
    }

    public static void main(String[] args) {
        new Main().foo();
        new Main().bar();
    }
}

And view the bytecode:

class my.pckage.Main extends java.lang.Object{
my.pckage.Main();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

int foo();
  Code:
   0:   iconst_0  //push zero onto the stack
   1:   istore_1  //pop off the stack and store in local variable
   2:   iload_1   //load an int value from local variable 1
   3:   ireturn   //return an integer from a method

int bar();
  Code:
   0:   iconst_0
   1:   ireturn

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   new     #2; //class my/pckage/Main
   3:   dup
   4:   invokespecial   #3; //Method "<init>":()V
   7:   invokevirtual   #4; //Method foo:()I
   10:  pop
   11:  new     #2; //class my/pckage/Main
   14:  dup
   15:  invokespecial   #3; //Method "<init>":()V
   18:  invokevirtual   #5; //Method bar:()I
   21:  pop
   22:  return

}

You can see that it's not being optimised away at this level.

As to whether the JIT compiler decides to optimise this at runtime will depend on the specific platform being targeted.

like image 84
Michael Avatar answered Oct 30 '25 10:10

Michael



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!