Codice compilato in java 8 vs codice compilato in java 11

Oct 07 2020

Al momento abbiamo del codice compilato in Java 8 ma lo stiamo eseguendo su Java 11 VM. Ora stiamo cercando di spostare anche il nostro codice nella fase di compilazione di Java 11. Ti chiedi se ci sono vantaggi nel codice compilato in Java 8 rispetto al codice compilato in Java 11 dal punto di vista delle prestazioni, poiché entrambi i compilatori produrranno file di classe diversi (bytecode)? Come si differenzia l'uno dall'altro in termini di efficienza?

Risposte

9 apangin Oct 07 2020 at 07:56

javacnon è un compilatore che ottimizza , quindi in generale non aspettarti che produca bytecode "più veloce" da una versione all'altra. L'ottimizzazione è un lavoro della JVM.

Nel frattempo, Java Compiler fa supportare le nuove funzionalità del linguaggio e può supportare le nuove funzionalità di JVM. Alcuni di loro hanno effettivamente implicazioni sulle prestazioni. Gli esempi più notevoli in JDK 9 - JDK 11 sono i seguenti.

  1. JEP 280: Indica concatenazione di stringhe (JDK 9).

    Questo JEP cambia il modo in cui vengono compilate le espressioni di concatenazione di stringhe. Prima di JDK 9, l' +espressione stringa veniva tradotta in

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

    Sebbene JIT riconosca tali catene e cerchi di ottimizzarle in runtime, questa ottimizzazione è fragile e non sempre funziona come previsto. La compilazione della concatenazione di stringhe con invokedynamicdà alla JVM più libertà di produrre codice migliore. È possibile trovare la spiegazione dettagliata e i benchmark nelle note a questo PEC.

  2. JEP 181: Controllo degli accessi basato su Nest (JDK 11)

    Questo JEP risolve il problema dell'accesso ai membri privati ​​delle classi annidate. Prima di JDK 11, Java Compiler generava per loro metodi bridge sintetici ( esempio ).

    A prima vista, questo non ha nulla a che fare con le prestazioni. Tuttavia, in casi marginali, un metodo sintetico aggiuntivo può interrompere l'inlining a causa del limite di profondità inlining.

    Il controllo degli accessi basato su Nest consente alle classi nestmate di accedere a membri privati ​​l'uno dell'altro senza ponti sintetici, riducendo così il rischio di degrado accidentale delle prestazioni.

Aggiornare

In precedenza ho incluso JDK-8175883: Bytecode Generation for Enhanced for Loop in questo elenco, ma come ha notato @Holger nei commenti, questa "ottimizzazione" non ha funzionato.

Conclusione

Le modifiche in Java Compiler sono principalmente correlate alle nuove funzionalità di linguaggio / JVM. L'ottimizzazione del livello di bytecode non è un obiettivo. Tuttavia, alcuni di questi cambiamenti possono (indirettamente) influenzare anche le prestazioni. Ad ogni modo, i possibili benefici in termini di prestazioni dalla ricompilazione del codice sono solitamente così piccoli che non li noterai nemmeno in un'applicazione reale.