Есть ли в java концепция встроенных функций или она заменена чем-то другим? Если есть, то как его использовать? Я слышал об этом public
, static
а final
методы - это встроенные функции. Можем ли мы создать нашу собственную встроенную функцию?
Есть ли в java концепция встроенных функций или она заменена чем-то другим? Если есть, то как его использовать? Я слышал об этом public
, static
а final
методы - это встроенные функции. Можем ли мы создать нашу собственную встроенную функцию?
Ответы:
В Java оптимизация обычно выполняется на уровне JVM. Во время выполнения JVM выполняет некоторый «сложный» анализ, чтобы определить, какие методы следует встроить. Он может быть агрессивным при встраивании, и JVM Hotspot фактически может встраивать неокончательные методы.
Компиляторы java почти никогда не встраивают вызов метода (JVM делает все это во время выполнения). Они делают встроенные константы времени компиляции (например, конечные статические примитивные значения). Но не методы.
Дополнительные ресурсы:
Статья: Механизм производительности Java HotSpot: пример встраивания методов
Wiki: встраивание в OpenJDK , заполнено не полностью, но содержит ссылки на полезные обсуждения.
Нет, в java нет встроенной функции . Да, вы можете использовать общедоступный статический метод в любом месте кода при помещении в открытый класс. Компилятор java может выполнять встроенное расширение для статического или конечного метода, но это не гарантируется.
Обычно такая оптимизация кода выполняется компилятором в сочетании с JVM / JIT / HotSpot для часто используемых сегментов кода. Также другие концепции оптимизации, такие как объявление параметров в регистре, не известны в java.
Оптимизация не может быть вызвана объявлением в java, но выполняется компилятором и JIT. Во многих других языках эти объявления часто являются только подсказками компилятора (вы можете объявить больше параметров регистра, чем имеет процессор, остальные игнорируются).
Объявление методов Java static, final или private также является подсказкой для компилятора. Стоит использовать, но никаких гарантий. Производительность Java динамическая, а не статическая. Первый вызов системы всегда выполняется медленно из-за загрузки класса. Следующие вызовы выполняются быстрее, но в зависимости от памяти и времени выполнения наиболее распространенные вызовы оптимизируются внутри работающей системы, поэтому сервер может работать быстрее во время выполнения!
final
не влияет на встраивание JIT
Java не позволяет вручную предлагать встроить метод. Как @notnoop говорит в комментариях, встраивание обычно выполняется JVM во время выполнения.
jdk.internal.vm.annotation.ForceInline
То, что вы сказали выше, правильно. Иногда final методы создаются как встроенные, но другого способа явно создать встроенную функцию в java нет.
final
даже не имеет значения, является ли метод встроенным или нет.
Пример из реальной жизни:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Затем в других классах я могу выйти, если срок действия кода истек. Если я ссылаюсь на переменную EXPIRED_ON из другого класса, константа встроена в байтовый код, что очень затрудняет отслеживание всех мест в коде, который проверяет дату истечения срока действия. Однако, если другие классы вызывают метод isExpired (), вызывается фактический метод, что означает, что хакер может заменить метод isExpired другим, который всегда возвращает false.
Я согласен, что было бы очень хорошо заставить компилятор встроить статический конечный метод во все классы, которые на него ссылаются. В этом случае вам даже не нужно включать класс Control, так как он не понадобится во время выполнения.
Судя по моим исследованиям, этого нельзя сделать. Возможно, некоторые инструменты обфускатора могут это сделать, или вы можете изменить процесс сборки, чтобы редактировать исходные коды перед компиляцией.
Что касается проверки того, размещен ли метод из класса управления встроенным в другой класс во время компиляции, попробуйте запустить другой класс без класса Control в пути к классам.
Что ж, в java есть методы, которые можно назвать "встроенными", но в зависимости от jvm. После компиляции, если машинный код метода меньше 35 байт, он будет немедленно передан во встроенный метод, если машинный код метода меньше 325 байт, он может быть передан во встроенный метод, в зависимости от jvm.
Итак, похоже, что нет, но вы можете использовать этот обходной путь, используя guava или эквивалентную реализацию класса Function, потому что этот класс чрезвычайно прост, например:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
да, это мертвый код, просто чтобы проиллюстрировать, как создать сложный блок кода (внутри {}), чтобы сделать что-то настолько конкретное, что не должно нас беспокоить при создании для него какого-либо метода, AKA inline!