Оптимизирует ли Java поле, которое просто служит возвращаемым значением? - PullRequest
0 голосов
/ 11 мая 2018

Почему я спрашиваю:

Я хотел бы знать, что на стороне компилятора происходит какая-либо оптимизация, которая делает один или другой метод возвращаемым предпочтительным.Поскольку я прочитал этот пост , то python не оптимизирует метод для более быстрого запуска.

Пример:

Я объявил 2 методакоторые доставляют ту же стоимость.Но barA возвращает его через объявление внутреннего поля.

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

    public int barB(){
        return 1;
    }
}

Тесты:

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());
    }
}

Результаты:

Тесты показали, что я вфакт, имеющий дело с одним и тем же значением и типом возврата в обоих методах.

Отказ от ответственности: Это изображение не предназначено для выделения секундомера, junit запускается для каждого метода, так как он никак не связанк оптимизации компилятора, о которой я спрашиваю.

The tests

Вопрос:

Действительно ли Java пытаетсяоптимизировать ненужные объявления полей для более быстрого выполнения?

Мне не удалось найти вопрос, касающийся этого.

Использование:

  • jdk 1.8.0_121
  • junit 4.10

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Если мы возьмем пример:

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();
    }
}

и просмотреть байт-код:

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

}

Вы можете видеть, что он не оптимизирован на этом уровне.

То, решит ли JIT-компилятор оптимизировать это во время выполнения, будет зависеть от конкретной целевой платформы.

0 голосов
/ 11 мая 2018

Учитывая обновления OP, реальный ответ здесь очень прост: java - это статически скомпилированный язык.

Подпись метода ... это то, что говорит подпись. В подписи написано, что нужно вернуть значение типа int. И это то, что вернет любой метод с int на своей подписи. Ничто в архитектуре Java не позволяет вам динамически изменять такие вещи во время выполнения. С этой точки зрения все ваши тесты для возвращаемого типа являются поддельными. Конструкция языка подразумевает, что ответом всегда является «метод возвращает int». И, пожалуйста, обратите внимание: если возвращаемый тип будет ссылочным типом, скажем, Number, то, конечно, у вас может быть один метод, возвращающий экземпляр Long, и еще один объект Integer (приводящий к различным типам, но все же подтипам Number)!

Помимо этого, ОП говорит о , глядя на разное время выполнения .

Да, junit запускает секундомер, чтобы примерно сказать вам, как долго выполняется каждый тест. Но это не измерение. Чтобы понять истинное влияние кода на производительность, вы должны сделать реальные измерения. С этой точки зрения: цифры от JUnit не означают того, что вы думаете, они имеют в виду. Они не являются подходящей основой для таких выводов.

См. Как написать правильный микро-тест в Java? для получения дополнительных указаний о том, как один может получить более значимые числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...