Czy w javie istnieje koncepcja funkcji inline, czy też została ona zastąpiona czymś innym? Jeśli tak, jak jest używany? Słyszałem, że public
, static
i final
metody są funkcje inline. Czy możemy stworzyć własną funkcję inline?
Czy w javie istnieje koncepcja funkcji inline, czy też została ona zastąpiona czymś innym? Jeśli tak, jak jest używany? Słyszałem, że public
, static
i final
metody są funkcje inline. Czy możemy stworzyć własną funkcję inline?
Odpowiedzi:
W Javie optymalizacje są zwykle wykonywane na poziomie JVM. W czasie wykonywania maszyna JVM przeprowadza „skomplikowaną” analizę, aby określić, które metody mają być wbudowane. Inlining może być agresywny, a wirtualna maszyna wirtualna Hotspot może w rzeczywistości wstawiać metody nieokończone.
Kompilatory java prawie nigdy nie wbudowują żadnej metody (JVM robi to wszystko w czasie wykonywania). Robią wbudowane stałe czasu kompilacji (np. Końcowe statyczne wartości pierwotne). Ale nie metody.
Aby uzyskać więcej zasobów:
Artykuł: Silnik wydajności Java HotSpot: przykład wstawiania metod
Wiki: Inlining w OpenJDK , nie w pełni zapełniony, ale zawiera linki do przydatnych dyskusji.
Nie, w java nie ma funkcji inline . Tak, po umieszczeniu w klasie publicznej publicznej metody statycznej można użyć w dowolnym miejscu kodu. Kompilator java może wykonywać rozwijanie inline w metodzie statycznej lub końcowej, ale nie jest to gwarantowane.
Zwykle takie optymalizacje kodu są wykonywane przez kompilator w połączeniu z JVM / JIT / HotSpot dla często używanych segmentów kodu. Również inne koncepcje optymalizacji, takie jak deklarowanie parametrów w rejestrze, nie są znane w Javie.
Optymalizacji nie można wymusić deklaracją w Javie, ale wykonuje ją kompilator i JIT. W wielu innych językach te deklaracje są często tylko wskazówkami kompilatora (można zadeklarować więcej parametrów rejestru niż ma procesor, pozostałe są ignorowane).
Deklarowanie metod java jako statyczne, końcowe lub prywatne jest również wskazówką dla kompilatora. Powinieneś go używać, ale bez gwarancji. Wydajność Java jest dynamiczna, a nie statyczna. Pierwsze wywołanie systemu jest zawsze powolne z powodu ładowania klas. Następne wywołania są szybsze, ale w zależności od pamięci i czasu wykonania, najczęściej używane wywołania są optymalizowane w działającym systemie, więc serwer może stać się szybszy w trakcie działania!
final
nie mają wpływu na inlining JIT
Java nie umożliwia ręcznego sugerowania, że metoda powinna być wbudowana. Jak @notnoop mówi w komentarzach, wstawianie jest zwykle wykonywane przez maszynę JVM w czasie wykonywania.
jdk.internal.vm.annotation.ForceInline
To, co powiedziałeś powyżej, jest poprawne. Czasami ostateczne metody są tworzone jako wbudowane, ale nie ma innego sposobu, aby jawnie utworzyć funkcję wbudowaną w java.
final
nie ma nawet znaczenia, czy metoda jest wbudowana, czy nie.
Przykład z życia:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Następnie w innych klasach mogę wyjść, jeśli kod wygasł. Jeśli odwołuję się do zmiennej EXPIRED_ON z innej klasy, stała jest wbudowana w kod bajtowy, co bardzo utrudnia śledzenie wszystkich miejsc w kodzie, które sprawdzają datę ważności. Jeśli jednak inne klasy wywołują metodę isExpired (), wywoływana jest właściwa metoda, co oznacza, że haker może zastąpić metodę isExpired inną, która zawsze zwraca wartość false.
Zgadzam się, byłoby bardzo miło zmusić kompilator do wstawienia statycznej metody końcowej do wszystkich klas, które się do niej odwołują. W takim przypadku nie musisz nawet dołączać klasy Control, ponieważ nie byłaby potrzebna w czasie wykonywania.
Z moich badań wynika, że nie można tego zrobić. Być może niektóre narzędzia Obfuscator mogą to zrobić lub możesz zmodyfikować proces kompilacji, aby edytować źródła przed kompilacją.
Jeśli chodzi o udowodnienie, czy metoda z klasy Control jest umieszczona w linii w innej klasie podczas kompilacji, spróbuj uruchomić drugą klasę bez klasy Control w ścieżce klas.
Cóż, istnieją metody, które można nazwać metodami „inline” w java, ale zależą one od jvm. Po kompilacji, jeśli kod maszynowy metody ma mniej niż 35 bajtów, zostanie natychmiast przeniesiony do metody wbudowanej, jeśli kod maszynowy metody jest mniejszy niż 325 bajtów, może zostać przeniesiony do metody wbudowanej, w zależności od jvm.
więc wygląda na to, że nie ma, ale możesz użyć tego obejścia, używając guawy lub równoważnej implementacji klasy funkcji, ponieważ ta klasa jest niezwykle prosta, np .:
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);
tak, to jest martwy kod tylko po to, aby zilustrować, jak utworzyć złożony blok kodu (w obrębie {}), aby zrobić coś tak specyficznego, że nie powinno nam przeszkadzać w tworzeniu żadnej metody do tego celu, AKA inline!