Skompilowany kod w java 8 vs skompilowany kod w java 11

Oct 07 2020

Obecnie mamy kod skompilowany w Javie 8, ale używamy go na maszynie wirtualnej Java 11. Teraz próbujemy również przenieść nasz kod do czasu kompilacji Java 11. Zastanawiasz się, czy są jakieś korzyści ze skompilowanego kodu w Javie 8 w porównaniu z kodem skompilowanym w Javie 11 pod względem wydajności, ponieważ oba kompilatory będą tworzyć różne pliki klas (kod bajtowy)? Czym różni się jeden od drugiego pod względem wydajności?

Odpowiedzi

9 apangin Oct 07 2020 at 07:56

javacto nie jest optymalizacja kodu wynikowego , więc w ogóle nie należy się spodziewać, że do produkcji „Faster” kodu bajtowego między wersjami. Optymalizacja jest zadaniem maszyny JVM.

Tymczasem Java Compiler ma wspierać nowe funkcje językowe i może obsługiwać nowe funkcje JVM. Niektóre z nich rzeczywiście mają wpływ na wydajność. Najbardziej godne uwagi przykłady w JDK 9 - JDK 11 są następujące.

  1. JEP 280: Wskaż konkatenację ciągów (JDK 9).

    Ten JEP zmienia sposób kompilowania wyrażeń konkatenacji ciągów. Przed JDK 9, +wyrażenie tekstowe zostało przetłumaczone na

    new StringBuilder().append()...append().toString();
    

    Chociaż JIT rozpoznaje takie łańcuchy i próbuje je optymalizować w czasie wykonywania, ta optymalizacja jest delikatna i nie zawsze działa zgodnie z oczekiwaniami. Kompilowanie konkatenacji ciągów za pomocą invokedynamicdaje JVM większą swobodę w tworzeniu lepszego kodu. Szczegółowe wyjaśnienie i wzorce można znaleźć w uwagach do tego JEP.

  2. JEP 181: Kontrola dostępu oparta na gniazdach (JDK 11)

    Ten JEP rozwiązuje problem dostępu do prywatnych członków klas zagnieżdżonych. Przed JDK 11 kompilator Java generował dla nich syntetyczne metody mostów ( przykład ).

    Na pierwszy rzut oka nie ma to nic wspólnego z wydajnością. Jednak w skrajnych przypadkach dodatkowa metoda syntetyczna może przerwać inlining z powodu ograniczenia głębokości inliningu.

    Nest-Based Access Control umożliwia klasom nestmate dostęp do swoich prywatnych członków bez mostków syntetycznych, zmniejszając w ten sposób ryzyko przypadkowego pogorszenia wydajności.

Aktualizacja

Wcześniej na tej liście umieściłem JDK-8175883: Generowanie kodu bajtowego dla ulepszonej pętli , ale jak zauważył @Holger w komentarzach, ta „optymalizacja” w rzeczywistości nie działała.

Wniosek

Zmiany w kompilatorze Java są głównie związane z nowym językiem / funkcjami JVM. Optymalizacja na poziomie kodu bajtowego nie jest celem. Jednak niektóre z tych zmian mogą (pośrednio) wpłynąć również na wydajność. W każdym razie możliwe korzyści wydajnościowe wynikające z ponownej kompilacji kodu są zwykle tak małe, że nawet nie zauważysz ich w prawdziwej aplikacji.