2010-01-19 4 views
88

Есть ли понятие встроенных функций в java, или его заменили что-то еще? Если есть, как он используется? Я слышал, что методы public, static и final являются встроенными функциями. Можем ли мы создать собственную встроенную функцию?Есть ли встроенные функции в java?

+3

Чтобы уточнить, вы имеете в виду http://en.wikipedia.org/wiki/Inline_function, а не http://en.wikipedia.org/wiki/Anonymous_function, правильно? –

+3

В качестве второстепенного комментария преждевременная оптимизация является корнем всего зла. Без полного понимания природы публичного, статического и окончательного вы не можете понять, какое влияние может иметь влияние inlining - и это зависит от используемой вами JVM. Не забудьте сначала ответить, почему вам нужно встроить что-то: почти наверняка есть более высокая оптимизация ROI, которую вы можете сделать в другом месте. –

+0

Также см. Http://stackoverflow.com/q/7772864/632951 – Pacerier

ответ

4

То, что вы сказали выше, является правильным. Иногда конечные методы создаются как встроенные, но нет другого способа явно создать встроенную функцию в java.

+4

Окончательные методы не гарантируются как встроенные. –

+3

В HotSpot добавление 'final' даже не имеет никакого значения, является ли метод встроенным или нет. –

+4

@Thomas - вот почему я сказал «Иногда последние методы ...» – GreenieMeanie

103

В Java оптимизация обычно выполняется на уровне JVM. Во время выполнения JVM выполняет некоторый «сложный» анализ, чтобы определить, какие методы встроены. Он может быть агрессивным в inlining, и JVM Hotspot на самом деле может встроить не конечные методы.

Компиляторы java практически никогда не выстраивают никакого вызова метода (JVM делает все это во время выполнения). Они выполняют встроенные константы времени компиляции (например, конечные статические примитивные значения). Но не методы.

Для получения дополнительной информации:

  1. Article: The Java HotSpot Performance Engine: Method Inlining Example

  2. Wiki: Inlining in OpenJDK, не полностью заполнен, но содержит ссылки на полезное обсуждение.

12

Java не дает возможности вручную предложить, чтобы метод был встроен. Как отмечает @notnoop в комментариях, inlining обычно выполняется JVM во время выполнения.

+3

Большинство java-компиляторов никогда не вызывает встроенные вызовы методов. В основном JVM делает это. – notnoop

+0

Спасибо за разъяснение. Я не был уверен, в какой именно фазе произошло. Я отредактирую свой пост, чтобы это отразить. –

9

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

Обычно такие оптимизации кода выполняются компилятором в сочетании с JVM/JIT/HotSpot для часто используемых сегментов кода. Кроме того, в java не известны другие концепции оптимизации, такие как декларация параметров регистра.

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

Объявление java-методов, статических, конечных или частных, также является подсказкой для компилятора. Вы должны использовать его, но никаких гарантий. Производительность Java динамическая, а не статическая. Первый вызов системы всегда медленный из-за загрузки классов. Следующие вызовы выполняются быстрее, но в зависимости от объема памяти и времени выполнения наиболее распространенные вызовы оптимизируются с запуском системы, поэтому сервер может ускориться во время работы!

+1

'final' не влияет на JIT-inlining –

+1

+1, но как мы можем ** проверить, включена ли скомпилированная версия метода? – Pacerier

2

Реальный пример из жизни:

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, поскольку он не понадобится во время выполнения.

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

Что касается проверки того, является ли метод из класса управления встроенным в другой класс во время компиляции, попробуйте запустить другой класс без класса Control в пути к классам.

0

Ну, есть методы, которые можно назвать «встроенными» методами в java, но в зависимости от jvm. После компиляции, если машинный код метода меньше 35 байт, он сразу же будет передан встроенному методу, если машинный код метода меньше 325 байт, он может быть перенесен в встроенный метод, в зависимости от jvm.

+0

Это значения * по умолчанию * для виртуальной машины Oracle, см. Http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html – rmuller

0

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

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!

+0

Похоже на разумную идею. У вас есть версия этого, которая не использует общие библиотеки google? – ragerdl

0

Java9 имеет компилятор «Вперед времени», который выполняет несколько оптимизаций во время компиляции, а не во время выполнения, что можно рассматривать как inlining.

Смежные вопросы