Вопрос

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

Встраивание с большей вероятностью произойдет, если рассматриваемый метод:

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

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

class A {
    final int foo() { return 3; }
}

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

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

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

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

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

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

Прочтите это, чтобы узнать о поведении встраивания.http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top