Встраивание в Java - PullRequest
       50

Встраивание в Java

36 голосов
/ 21 июля 2009

В C ++ я могу объявить метод "inline", и компилятор, скорее всего, его встроит. Насколько я понимаю, в Java нет такого ключевого слова.

Встраивание выполняется, если JVM решит это сделать? Могу ли я как-то повлиять на это решение?

Ответы [ 8 ]

51 голосов
/ 21 июля 2009

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

По сути, пусть JVM выполнит свою работу - вероятно, будет гораздо лучше определить, куда подключиться, чем вам.

Есть ли у вас ситуация, когда вы убеждены, что JVM не справляется с работой? Предполагая, что вы используете HotSpot, вы пытались использовать версию сервера вместо клиента? Это может иметь огромное значение .

6 голосов
/ 21 июля 2009

Хотя java-компилятор может выполнять inline (для коротких ранних методов), real inline будет выполняться JIT-компилятором. JIT (HotSpot) компилятор сможет даже встроить виртуальные методы. Лучший способ взаимодействия с ним - написать простой и лаконичный код. Скорее всего, код, который использует Reflection, не позволит встроить.

Надеюсь, это поможет.

5 голосов
/ 21 июля 2009

'В C ++ я могу объявить метод "inline", и компилятор встроит его " ... или нет. Компилятор может сделать функцию встроенной или нет, и вы не можете реально повлиять на результат. Это только подсказка компилятору.

В Java такого нет, компилятор (а затем и виртуальная машина при выполнении оптимизаций) может решить "встроить" метод.

Обратите внимание, что методы final имеют больше шансов быть встроенными (компилятор не может встроить не финальные методы, поскольку они могут быть перезаписаны в производных классах). С современной виртуальной машиной аналогичная оптимизация может быть выполнена во время выполнения. Виртуальная машина помечает тип (чтобы она могла выполнять проверки типов) и вставляет код. Только если проверка не пройдена, она вернется к исходному неоптимизированному вызову полиморфного метода.

4 голосов
/ 21 июля 2009

Встраивание более вероятно, если рассматриваемый метод:

  • короткий
  • окончательный
  • не зависит ни от каких длинных, не финальных методов

Поскольку это единственные обстоятельства, когда JVM может быть уверена в последствиях вызова.

2 голосов
/ 21 июля 2009
class A {
    final int foo() { return 3; }
}

Учитывая этот класс, любой вызов foo () может быть заменен константой "3". Любая виртуальная машина Java1 может сделать это, потому что ключевое слово final явно диктует, что невозможно иметь подкласс, который переопределяет "int foo ()".

Встраивание метода обеспечивает следующие преимущества на сайте вызова:

  • Нет вызова метода
  • Нет динамической отправки
  • Возможно постоянное сгибание значения, например. «a.foo () + 2» становится 5 без кода, выполненного в
    во время выполнения.

В прошлом программисты часто вставляли ключевое слово final именно по этой причине . Или, чтобы лучше упростить встраивание и увеличить скорость выполнения, они объединили бы много меньших методов в один больший метод. Но во многих отношениях такие методы побеждают все средства модульности и возможности повторного использования, встроенные в язык программирования.

Современная JVM, как и Java HotSpot VM, может встроить класс без final . Ключевое слово **.

(http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html)

1 голос
/ 13 августа 2014

При сравнении нормальной функции и конечной функции (которая называется встроенной в JVM), я увидел, что между ними нет улучшения производительности. Возможно, накладные расходы на вызов функции уже очень низкие.

Примечание. Я использовал алгоритм размытия рамки для оценки производительности.

1 голос
/ 21 июля 2009

Да, если JVM решит это сделать, может. Способы влияния включают установку метода как статического или как окончательного.

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

Однако вам не следует делать такие оптимизации преждевременно, на самом деле вы можете ухудшать ситуацию (потому что вы можете закорачивать другие потенциальные оптимизации). JVM иногда понимает, что метод может быть встроен без этих подсказок.

1 голос
/ 21 июля 2009

Прочитайте это для поведения Inlining. http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html

В нем говорится, что финальные методы могут быть встроенными, но не всегда.

...