Байт-код Java iconst_0 последовательность iadd - PullRequest
2 голосов
/ 23 февраля 2010

Вот тест для развлечения с троичным оператором:

public int so( final int a ) {
    int r = (int) System.currentTimeMillis();
    r += a == 2 ? 1 : 0;
    return r;
}

Вот полученный байт-код:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_2
   6:   iload_1
   7:   iconst_2
   8:   if_icmpne       15
   11:  iconst_1
   12:  goto    16
   15:  iconst_0
   16:  iadd
   17:  istore_2
   18:  iload_2
   19:  ireturn

Я был немного удивлен, увидев, что это не убирает случай 'else' для '+ 0'. Я больше ожидал этого:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_1
   6:   iconst_2
   7:   if_icmpne       13
   10:  iinc    2, 1
   13:  iload_2
   14:  ireturn

Итак, вот мой вопрос: мандаты спецификации:

goto ...
iconst_0

последовательность, потому что я использовал троичный оператор, или это просто вещь компилятора?

Очевидно, этот вопрос не об актуальности написания 'r + = ...? 1: 0 '. Но я удивлен, потому что в других случаях компилятор выполняет некоторую оптимизацию, в то время как здесь он не выполняет никакой оптимизации.

Будет ли компилятор Java, производящий вариант 2, по-прежнему действительным компилятором Java (в случае, если я не привинтил свой пример, но суть в том, что в создаваемом коде есть ненужное добавление 0 и ненужное перемещение, будет ли компилятор удаление этого все еще будет действительным компилятором .java)?

Ответы [ 2 ]

3 голосов
/ 23 февраля 2010

Следует помнить, что javac (компилятор исходного кода Java в байтовый код) - это , а не оптимизирующий компилятор. На самом деле, он относительно прост в генерации кода и производит только самую прямую реализацию байт-кода из любого данного исходного кода.

Это полностью задумано. Таким образом, JVM, отвечающая за все реальные оптимизации, имеет максимальный объем доступной информации, на которой можно основывать свои решения. В этом конкретном случае может быть неочевидно, как эта информация может принести пользу JIT-компилятору, но из-за характера оптимизаций, выполняемых, например, HotSpot, каждый бит информации может помочь.

Например, может быть какое-то умное сопоставление с образцом, которое распознает общие части кода и реализует их в высокооптимизированной версии. Теперь, если javac также попытается провести некоторую оптимизацию, обнаружить эти шаблоны будет гораздо сложнее.

2 голосов
/ 23 февраля 2010

Сам Javac от Sun не выполняет никаких оптимизаций, поскольку они оставлены для виртуальной машины HotSpot. Таким образом, он производит первый байт-код.

Второй список байт-кода действителен так же, как и первый. Так что теоретически какой-то другой Java-компилятор мог бы создать это.

Если такой тип оптимизации необходим для виртуальных машин, у которых нет JIT (например, для устройств Android), существуют такие инструменты, как Proguard, которые выполняют оптимизации на уровне байт-кода.

...