Cosa fa un compilatore JIT (just-in-time)?

Cosa fa specificamente un compilatore JIT rispetto a un compilatore non JIT? Qualcuno può dare una descrizione succinta e facile da capire?

    Un compilatore JIT viene eseguito dopo che il programma è stato avviato e compila il codice (di solito bytecode o qualche tipo di istruzioni VM) al volo (o just-in-time, come viene chiamato) in una forma che è solitamente più veloce, tipicamente il processore della CPU host set di istruzioni. Un JIT ha accesso a informazioni di runtime dinamiche mentre un compilatore standard non lo fa e può fare migliori ottimizzazioni come l’inlining di funzioni che vengono usate frequentemente.

    Ciò è in contrasto con un compilatore tradizionale che compila tutto il codice sul linguaggio macchina prima che il programma venga eseguito per la prima volta.

    Per parafrasare, i compilatori convenzionali costruiscono l’intero programma come un file EXE PRIMA della prima esecuzione. Per i nuovi programmi di stile, viene generato un assembly con pseudocode (p-code). Solo DOPO aver eseguito il programma sul sistema operativo (ad esempio, facendo doppio clic sulla sua icona) il compilatore (JIT) eseguirà il kick-in generando codice macchina (codice m) che il processore basato su Intel o qualsiasi altra cosa comprenderà.

    All’inizio, un compilatore era responsabile della trasformazione di un linguaggio di alto livello (definito come livello superiore rispetto all’assemblatore) in codice object (istruzioni macchina), che sarebbe quindi collegato (da un linker) a un eseguibile.

    Ad un certo punto dell’evoluzione dei linguaggi, i compilatori compilano un linguaggio di alto livello in pseudo-codice, che sarebbe poi interpretato (da un interprete) per eseguire il programma. Questo ha eliminato il codice object e gli eseguibili e ha permesso che questi linguaggi fossero portabili su più sistemi operativi e piattaforms hardware. Pascal (che è stato compilato in P-Code) è stato uno dei primi; Java e C # sono esempi più recenti. Alla fine il termine P-Code è stato sostituito con bytecode, poiché la maggior parte delle pseudo-operazioni sono lunghe un byte.

    Un compilatore JIT (Just-In-Time) è una funzione dell’interprete run-time, che invece di interpretare bytecode ogni volta che viene invocato un metodo, compilerà il bytecode nelle istruzioni del codice macchina della macchina in esecuzione e quindi invocherà questo codice object invece. Idealmente l’efficienza del codice object in esecuzione supererà l’inefficienza della ricompilazione del programma ogni volta che viene eseguito.

    JIT-Just in tempo la parola stessa dice quando è necessario (su richiesta)

    Scenario tipico:

    Il codice sorgente è completamente convertito in codice macchina

    Scenario JIT:

    Il codice sorgente verrà convertito in linguaggio assembly come struttura [per ex IL (linguaggio intermedio) per C #, ByteCode per java].

    Il codice intermedio viene convertito in linguaggio macchina solo quando l’applicazione richiede che i codici richiesti vengano convertiti solo in codice macchina.

    Confronto tra JIT e Non JIT:

    • In JIT non tutto il codice viene convertito in codice macchina, prima una parte del codice che sarà necessario verrà convertita in codice macchina, quindi se un metodo o funzionalità chiamata non è in macchina allora verrà trasformato in codice macchina … si riduce carico sulla CPU.

    • Poiché il codice macchina verrà generato in fase di esecuzione …. il compilatore JIT produrrà un codice macchina ottimizzato per l’esecuzione dell’architettura CPU della macchina.

    Esempi JIT:

    1. In Java JIT è in JVM (Java Virtual Machine)
    2. In C # è in CLR (Common Language Runtime)
    3. In Android è in DVM (Dalvik Virtual Machine) o ART (Android RunTime) nelle versioni più recenti.

    Come altri hanno menzionato

    JIT sta per Just-in-Time, il che significa che il codice viene compilato quando è necessario, non prima del runtime.

    Solo per aggiungere un punto alla discussione sopra, JVM mantiene un conteggio di quante volte viene eseguita una funzione. Se questo conteggio supera un limite predefinito, JIT compila il codice nel linguaggio macchina che può essere eseguito direttamente dal processore (diversamente dal caso normale in cui javac compila il codice in bytecode e poi java – l’interprete interpreta questo bytecode riga per riga lo converte in codice macchina ed eseguito).

    Anche la prossima volta che questa funzione viene calcasting, lo stesso codice compilato viene eseguito nuovamente a differenza della normale interpretazione in cui il codice viene interpretato di nuovo riga per riga. Questo rende l’esecuzione più veloce.

    JIT sta per Just-in-Time, il che significa che il codice viene compilato quando è necessario, non prima del runtime.

    Questo è utile perché il compilatore può generare codice ottimizzato per la tua macchina particolare. Un compilatore statico, come il tuo compilatore C medio, compilerà tutto il codice sul codice eseguibile sulla macchina dello sviluppatore. Quindi il compilatore eseguirà ottimizzazioni basate su alcune ipotesi. Può compilare più lentamente e fare più ottimizzazioni perché non rallenta l’esecuzione del programma per l’utente.

    Dopo che il codice byte (che è neutro dell’architettura) è stato generato dal compilatore Java, l’esecuzione sarà gestita dalla JVM (in Java). Il codice byte verrà caricato in JVM dal caricatore e quindi ogni istruzione di byte viene interpretata.

    Quando abbiamo bisogno di chiamare un metodo più volte, dobbiamo interpretare lo stesso codice molte volte e questo potrebbe richiedere più tempo del necessario. Quindi abbiamo i compilatori JIT (just-in-time). Quando il byte è stato caricato in JVM (il suo tempo di esecuzione), l’intero codice verrà compilato anziché interpretato, risparmiando così tempo.

    I compilatori JIT funzionano solo durante il runtime, quindi non abbiamo alcun output binario.

    Compilatore JIT compila solo il codice byte in codice nativo equivalente alla prima esecuzione. Ad ogni esecuzione successiva, la JVM utilizza semplicemente il codice nativo già compilato per ottimizzare le prestazioni.

    inserisci la descrizione dell'immagine qui

    Senza il compilatore JIT, l’interprete JVM traduce il codice byte riga per riga in modo che appaia come se fosse in esecuzione un’applicazione nativa.

    inserisci la descrizione dell'immagine qui

    fonte

    Just in Time Compiler (JIT):
    Compila i bytecode java in istruzioni macchina di quella specifica CPU.

    Ad esempio, se abbiamo un’istruzione loop nel nostro codice java:

    while(i<10){ // ... a=a+i; // ... } 

    Il codice di loop sopra riportato viene eseguito per 10 volte se il valore di i è 0.

    Non è necessario compilare il bytecode per 10 volte ancora e ancora, poiché la stessa istruzione verrà eseguita per 10 volte. In tal caso, è necessario compilare quel codice solo una volta e il valore può essere modificato per il numero richiesto di volte. Quindi, il compilatore JIT (Just In Time) tiene traccia di tali dichiarazioni e metodi (come detto sopra prima) e compila tali codici byte in codice macchina per ottenere prestazioni migliori.

    Un altro esempio simile è la ricerca di un pattern usando "Regular Expression" in un elenco di stringhe / frasi.

    Compilatore JIT non compila tutto il codice al codice macchina. Compila codice che ha uno schema simile in fase di esecuzione.

    Vedi questa documentazione Oracle su Understand JIT per saperne di più.

    Hai codice che è integrato in alcune IL (linguaggio intermedio). Quando esegui il tuo programma, il computer non capisce questo codice. Comprende solo il codice nativo. Quindi il compilatore JIT compila il tuo IL in codice nativo al volo. Lo fa a livello di metodo.

    So che questo è un thread vecchio, ma l’ottimizzazione del runtime è un’altra parte importante della compilation JIT che non sembra essere discussa qui. Fondamentalmente, il compilatore JIT può monitorare il programma mentre viene eseguito per determinare i modi per migliorare l’esecuzione. Quindi, può apportare tali cambiamenti al volo – durante il runtime. Ottimizzazione JIT di Google (javaworld ha un buon articolo a riguardo ) .

    Jit sta per just in time compiler jit è un programma che trasforma il codice byte java in istruzioni che possono essere inviate direttamente al processore.

    L’uso del compilatore java just in time (in realtà un secondo compilatore) sulla particolare piattaforma di sistema rispetta il bytecode in un particolare codice di sistema, una volta che il codice è stato ricompilato dal compilatore jit, di solito viene eseguito più rapidamente nel computer.

    Il compilatore just-in-time viene fornito con la macchina virtuale e viene utilizzato facoltativamente. Compila il bytecode in codice eseguibile specifico della piattaforma che viene immediatamente eseguito.

    Un compilatore non JIT acquisisce il codice sorgente e lo trasforma in codice byte specifico della macchina in fase di compilazione. Un compilatore JIT prende il codice byte agnostico della macchina che è stato generato in fase di compilazione e lo trasforma in codice byte specifico della macchina in fase di esecuzione. Il compilatore JIT utilizzato da Java è ciò che consente a un singolo binario di funzionare su una moltitudine di piattaforms senza modifiche.

    I seguenti esempi di codice mostrano come il JIT ottimizza il codice Java.

    Codice prima dell’ottimizzazione

      class A { B b; public void newMethod() { y = b.get(); ...do stuff... z = b.get(); sum = y + z; } } class B { int value; final int get() { return value; } } 

    Codice dopo l’ottimizzazione

     class A { B b; public void newMethod() { y = b.value; ...do stuff... sum = y + y; } } class B { int value; final int get() { return value; } } 

    Originariamente, il codice conteneva due chiamate al metodo b.get (). Dopo l’ottimizzazione, le due chiamate al metodo vengono ottimizzate in un’unica operazione di copia variabile; cioè, il codice ottimizzato non ha bisogno di eseguire una chiamata al metodo per acquisire il valore del campo della class B.

    la compilazione just-in-time (JIT), (anche la traduzione dynamic o la compilazione in fase di esecuzione ), è un modo di eseguire codice di computer che implica la compilazione durante l’esecuzione di un programma – in fase di esecuzione – piuttosto che prima dell’esecuzione .

    La compilazione IT è una combinazione dei due approcci tradizionali alla traduzione al codice macchina – compilazione anticipata (AOT) e interpretazione – e combina alcuni vantaggi e svantaggi di entrambi. La compilazione JIT combina la velocità del codice compilato con la flessibilità dell’interpretazione .

    Consideriamo JIT utilizzato in JVM,

    Ad esempio, i compilatori JIT JVM HotSpot generano ottimizzazioni dinamiche. In altre parole, prendono decisioni di ottimizzazione mentre l’applicazione Java è in esecuzione e generano istruzioni macchina native ad alte prestazioni mirate all’architettura di sistema sottostante.

    Quando viene scelto un metodo per la compilazione, la JVM invia il suo bytecode al compilatore Just-In-Time (JIT). Il JIT deve comprendere la semantica e la syntax del bytecode prima che possa compilare correttamente il metodo. Per aiutare il compilatore JIT ad analizzare il metodo, il suo bytecode viene prima riformulato in una rappresentazione interna denominata trace trees, che assomiglia più al codice macchina che al codice bytecode. Analisi e ottimizzazioni vengono quindi eseguite sugli alberi del metodo. Alla fine, gli alberi sono tradotti in codice nativo.

    Un albero delle tracce è una struttura dati che viene utilizzata nella compilazione runtime del codice di programmazione. Gli alberi di traccia vengono utilizzati in un tipo di compilatore “just in time” che traccia il codice in esecuzione durante gli hotspot e lo compila. Riferiscilo.

    Fare riferimento :

    Il 20% del codice byte viene utilizzato l’80% delle volte. Il compilatore JIT ottiene queste statistiche e ottimizza questo 20% del codice byte per funzionare più velocemente aggiungendo metodi in linea, rimozione di blocchi inutilizzati ecc. E creando anche il bytecode specifico per quella macchina. Sto citando da questo articolo, ho trovato che era a portata di mano. http://java.dzone.com/articles/just-time-compiler-jit-hotspot

    JIT si riferisce al motore di esecuzione in alcune delle implementazioni JVM, uno più veloce ma che richiede più memoria, è un compilatore just-in-time. In questo schema, i bytecode di un metodo vengono compilati nel codice macchina nativo la prima volta che viene richiamato il metodo. Il codice macchina nativo per il metodo viene quindi memorizzato nella cache, quindi può essere riutilizzato la volta successiva in cui viene richiamato lo stesso metodo.

    JVM esegue effettivamente i passaggi di compilazione durante il runtime per motivi di prestazioni. Ciò significa che Java non ha una separazione di compilazione-esecuzione pulita. Prima esegue una cosiddetta compilazione statica dal codice sorgente Java al bytecode. Quindi questo bytecode viene passato alla JVM per l’esecuzione. Ma l’esecuzione di bytecode è lenta, quindi la JVM misura la frequenza con cui viene eseguito il bytecode e quando rileva un “hotspot” di codice eseguito molto frequentemente esegue la compilazione dynamic da bytecode a codice macchina del codice “hotspot” (hotspot profiler). Così efficacemente oggi i programmi Java vengono eseguiti tramite l’esecuzione del codice macchina.