web-dev-qa-db-fra.com

Que fait un compilateur juste à temps (JIT)?

Que fait spécifiquement un compilateur JIT par opposition à un compilateur non-JIT? Quelqu'un peut-il donner une description succincte et facile à comprendre?

483
Michiel Borkent

Un compilateur JIT fonctionne après le programme a démarré et compile le code (généralement du bytecode ou une sorte d’instructions VM) à la volée (ou juste à temps, comme on l’appelle ) sous une forme généralement plus rapide, généralement le jeu d'instructions natives du processeur hôte. Un JIT a accès aux informations d'exécution dynamiques, alors qu'un compilateur standard ne le peut pas et peut effectuer de meilleures optimisations, telles que les fonctions en ligne fréquemment utilisées.

Ceci est en contraste avec un compilateur traditionnel qui compile tout le code en langage machine avant le programme est exécuté pour la première fois.

Pour paraphraser, les compilateurs classiques construisent l'ensemble du programme sous la forme d'un fichier EXE AVANT la première exécution. Pour les programmes de style plus récent, un assemblage est généré avec un pseudocode (p-code). APRÈS avoir exécuté le programme sur le système d'exploitation (par exemple, en double-cliquant sur son icône), le compilateur (JIT) démarrera et générera un code machine (m-code) que le processeur Intel ou tout autre système comprendra.

483
Mark Cidade

Au début, un compilateur était chargé de convertir un langage de haut niveau (défini comme étant de niveau supérieur à celui de l'assembleur) en code objet (instructions machine), qui serait ensuite lié (par un éditeur de liens) à un exécutable.

À un moment de l'évolution des langages, les compilateurs compileraient un langage de haut niveau en pseudo-code, qui serait ensuite interprété (par un interprète) pour exécuter votre programme. Cela éliminait le code objet et les exécutables et permettait à ces langages d'être portables sur plusieurs systèmes d'exploitation et plates-formes matérielles. Pascal (compilé dans P-Code) a été l'un des premiers; Java et C # sont des exemples plus récents. Finalement, le terme P-Code a été remplacé par bytecode, car la plupart des pseudo-opérations ont une longueur en octets.

Un compilateur Just-In-Time (JIT) est une fonctionnalité de l'interpréteur au moment de l'exécution qui, au lieu d'interpréter le bytecode chaque fois qu'une méthode est invoquée, compilera le bytecode dans les instructions de code machine de la machine en cours d'exécution, puis l'invoque. code d'objet à la place. Idéalement, l'efficacité du code objet en cours d'exécution résoudra l'inefficacité de la recompilation du programme à chaque exécution.

243
Craig Trader

JIT-Juste à temps, la Parole elle-même dit quand c'est nécessaire (sur demande)

Scénario typique:

Le code source est complètement converti en code machine

Scénario JIT:

Le code source sera converti en langage Assembly comme structure [pour ex IL (langage intermédiaire) pour C #, ByteCode pour Java].

Le code intermédiaire est converti en langage machine uniquement lorsque l'application a besoin que les codes requis soient uniquement convertis en code machine.

Comparaison JIT vs non-JIT:

  • Dans JIT, tout le code n'est pas tout d'abord converti en code machine. Une partie du code nécessaire est ensuite convertie en code machine, puis si une méthode ou une fonctionnalité appelée n'est pas dans la machine, elle sera ensuite convertie en code machine. charge sur le processeur.

  • Comme le code machine sera généré au moment de l'exécution, le compilateur JIT produira un code machine optimisé pour l'exécution de l'architecture de processeur de la machine.

Exemples JIT:

  1. Dans Java JIT est dans JVM (Java Virtual Machine)
  2. En C # c'est en CLR (Common Language Runtime)
  3. Dans Android, il est en DVM (Dalvik Virtual Machine) ou ART (Android RunTime) dans les versions les plus récentes.
66
Durai Amuthan.H

Comme d'autres l'ont mentionné

JIT signifie Just-in-Time, ce qui signifie que le code est compilé quand il est nécessaire, pas avant l'exécution.

Juste pour ajouter un point à la discussion ci-dessus, JVM conserve un nombre de fois le temps d'exécution d'une fonction. Si ce nombre dépasse une limite prédéfinie, JIT compile le code en langage machine pouvant être exécuté directement par le processeur (contrairement au cas normal dans lequel javac compile le code en bytecode puis Java - l'interpréteur interprète ce bytecode. ligne par ligne le convertit en code machine et l'exécute).

De même, la prochaine fois que cette fonction est calculée, le même code compilé est exécuté à nouveau, contrairement à l'interprétation normale dans laquelle le code est interprété à nouveau ligne par ligne. Cela rend l'exécution plus rapide.

25
Aniket Thakur

Le compilateur JIT compile uniquement le code d'octet en code natif équivalent lors de la première exécution. À chaque exécution successive, la JVM utilise simplement le code natif déjà compilé pour optimiser les performances.

enter image description here

Sans compilateur JIT, l'interpréteur JVM convertit ligne par ligne le code octet pour lui donner l'apparence d'une application native en cours d'exécution.

enter image description here

Source

11
user8885515

Une fois que le code d'octet (qui est neutre sur le plan de l'architecture) a été généré par le compilateur Java, l'exécution sera gérée par la machine virtuelle Java (en Java). Le code d'octet sera chargé dans la machine virtuelle Java par le chargeur, puis chaque instruction d'octet est interprétée.

Lorsque nous devons appeler une méthode plusieurs fois, nous devons interpréter le même code plusieurs fois, ce qui peut prendre plus de temps que nécessaire. Nous avons donc les compilateurs JIT (juste à temps). Lorsque l'octet est chargé dans la machine virtuelle Java (son temps d'exécution), tout le code est compilé plutôt qu'interprété, ce qui permet de gagner du temps.

Les compilateurs JIT ne fonctionnent que pendant l'exécution, nous n'avons donc aucune sortie binaire.

9
User

JIT signifie Just-in-Time, ce qui signifie que le code est compilé quand il le faut, pas avant l'exécution.

Cela est avantageux car le compilateur peut générer du code optimisé pour votre machine particulière. Un compilateur statique, comme votre compilateur C moyen, compilera tout le code en code exécutable sur la machine du développeur. Par conséquent, le compilateur effectuera des optimisations basées sur certaines hypothèses. Il peut compiler plus lentement et faire plus d'optimisations car il ne ralentit pas l'exécution du programme pour l'utilisateur.

9
Brian Lyttle

Compilateur Just In Time (JIT):
Il compile les Java bytecodes en instructions machine de ce CPU spécifique.

Par exemple, si nous avons une instruction de boucle dans notre code Java:

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

Le code de boucle ci-dessus est lu 10 fois si la valeur de i est 0.

Il n'est pas nécessaire de compiler le code intermédiaire 10 fois, car la même instruction sera exécutée 10 fois. Dans ce cas, il est nécessaire de compiler ce code une seule fois et la valeur peut être modifiée le nombre de fois requis. Donc, Just In Time (JIT) compilateur garde une trace de ces déclarations et méthodes (comme indiqué ci-dessus précédemment) et compile ces morceaux de code octet en code machine pour de meilleures performances.

Un autre exemple similaire est la recherche d'un motif utilisant "Expression régulière" dans une liste de chaînes/phrases.

JIT Compiler ne compile pas tout le code en code machine. Il compile le code qui a un modèle similaire au moment de l'exécution.

Voir ceci documentation Oracle sur Understand JIT pour en savoir plus.

7
Anands23

Je sais que c'est un vieux fil de discussion, mais l'optimisation de l'exécution est un autre élément important de la compilation JIT qui ne semble pas avoir été discuté ici. Fondamentalement, le compilateur JIT peut surveiller le programme pendant son exécution pour déterminer les moyens d’améliorer l’exécution. Ensuite, il peut effectuer ces modifications à la volée - pendant l'exécution. Optimisation Google JIT (javaworld a un joli bon article à ce sujet. )

4
eze

Vous avez un code qui est compilé dans une certaine IL (langage intermédiaire). Lorsque vous exécutez votre programme, l'ordinateur ne comprend pas ce code. Il ne comprend que le code natif. Le compilateur JIT compile donc votre IL en code natif à la volée. Cela se fait au niveau de la méthode.

4
Charles Graham

Un compilateur juste-à-temps (JIT) est un logiciel qui reçoit une entrée non exécutable et renvoie le code machine approprié à exécuter. Par exemple:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

La conséquence en est que pour une certaine architecture de processeur, le compilateur JIT approprié doit être installé.

Compilateur de différences, interprète et JIT

Bien qu'il puisse y avoir des exceptions en général lorsque nous voulons transformer le code source en code machine, nous pouvons utiliser:

  1. Compiler: Prend le code source et retourne un exécutable
  2. Interpreter: Exécute l'instruction du programme, instruction par instruction. Il prend un segment exécutable du code source et transforme ce segment en instructions machine. Ce processus est répété jusqu'à ce que tout le code source soit transformé et exécuté en instructions machine.
  3. JIT: De nombreuses implémentations différentes d'un JIT sont possibles. Cependant, un JIT est généralement une combinaison d'un complémenteur et d'un interpréteur. Le JIT commence par transformer les données intermédiaires (par exemple, Java bytecode) qu’il reçoit en langage machine par interprétation. Une JIT peut souvent détecter le moment où une certaine partie du code est exécutée et la compiler pour une exécution plus rapide.
3
Willem van der Veen

Jit est un programme qui transforme le code d'octet Java en instructions pouvant être envoyées directement au processeur.

L'utilisation du compilateur juste-à-temps Java (en réalité un deuxième compilateur) sur une plate-forme système donnée convertit le code binaire en code système particulier, une fois que le code a été recompilé par le fournisseur jit, rapidement dans l'ordinateur.

Le compilateur juste à temps est fourni avec la machine virtuelle et est utilisé en option. Il compile le bytecode en un code exécutable spécifique à la plate-forme qui est immédiatement exécuté.

2
user3459027

la compilation JIT (Just-In-Time), (également traduction dynamique ou compilation à l'exécution), est un moyen d'exécuter du code informatique qui implique la compilation lors de l'exécution d'un programme - au moment de l'exécution - plutôt qu'avant l'exécution .

La compilation informatique est une combinaison de des deux approches traditionnelles de la traduction en code machine - en vue de la compilation anticipée ( AOT) , et interprétation - et combine certains avantages et inconvénients des deux. La compilation JIT associe la vitesse du code compilé à la souplesse d’interprétation .

Considérons JIT utilisé dans JVM,

Par exemple, les compilateurs HotSpot JVM JIT génèrent des optimisations dynamiques. En d’autres termes, , ils prennent des décisions d’optimisation lorsque l’application Java est en cours d’exécution et génèrent des instructions machine natives très performantes destinées au sous-jacent. Architecture du système.

Lorsqu'une méthode est choisie pour la compilation, la machine virtuelle Java envoie son bytecode au compilateur Just-In-Time (JIT). Le JIT doit comprendre la sémantique et la syntaxe du bytecode avant de pouvoir compiler la méthode correctement. Pour aider le compilateur JIT à analyser la méthode, ses codes octets sont d’abord reformulés dans une représentation interne appelée arborescences, qui ressemble davantage au code machine au code octet. Des analyses et des optimisations sont ensuite effectuées sur les arbres de la méthode. À la fin, les arbres sont traduits en code natif.

Une arborescence de trace est une structure de données utilisée dans la compilation du code de programmation à l'exécution. Les arborescences de trace sont utilisées dans un type de 'compilateur juste à temps' qui trace le code exécuté pendant les hotspots et le compile. Reportez-vous à this .

Référer :

1
prime

Un compilateur non-JIT prend le code source et le transforme en code octet spécifique à la machine lors de la compilation. Un compilateur JIT prend du code octet indépendant de la machine généré lors de la compilation et le transforme en code octet spécifique à la machine lors de l'exécution. Le compilateur JIT utilisé par Java permet à un seul binaire de s'exécuter sur une multitude de plates-formes sans modification.

1
David

Les exemples de code suivants montrent comment le JIT optimise le code Java.

Code avant optimisation

    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;
   }
}

Code après optimisation

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

À l'origine, le code contenait deux appels à la méthode b.get (). Après optimisation, les deux appels de méthode sont optimisés en une seule opération de copie variable. en d'autres termes, le code optimisé n'a pas besoin d'effectuer un appel de méthode pour acquérir la valeur de champ de la classe B.

1

À l'aide d'un compilateur JIT, le code source Java est converti en code Java byte (fichiers .class). Une fois cette opération effectuée, JVM charge les fichiers .class au moment de l’exécution et les convertit en un code compréhensible par la machine à l’aide d’un interpréteur.

Le compilateur JIT est une fonctionnalité de la machine virtuelle Java qui, lorsqu'elle est activée, permet à la machine virtuelle Java d'analyser les appels de méthode en code octet et de les compiler en un code plus natif et efficace. JIT optimise les appels de méthode hiérarchisés à ce moment.

Une fois ces appels de méthode compilés, la machine virtuelle Java exécute ensuite ce code optimisé au lieu de l’interpréter, ce qui risque d’accroître les performances de l’exécution.

plutôt que le compilateur ordinaire qui doit compiler le code source à chaque exécution du programme

0
sabeen kanwal

La machine virtuelle Java exécute des étapes de compilation pendant l'exécution pour des raisons de performances. Cela signifie que Java ne possède pas de séparation nette entre compilation et exécution. Il effectue d’abord une compilation dite statique de code source Java en bytecode. Ensuite, ce bytecode est transmis à la machine virtuelle Java pour exécution. Mais l’exécution du bytecode étant lente, la JVM mesure la fréquence d’exécution du bytecode et, lorsqu'elle détecte un "hotspot" de code exécuté très fréquemment, elle effectue une compilation dynamique du bytecode vers le machinecode du code "hotspot" (profileur de hotspot). Ainsi, les programmes Java sont aujourd'hui exécutés de manière machinecode.

0
hi.nitish

20% du code d'octet est utilisé 80% du temps. Le compilateur JIT obtient ces statistiques et optimise l’exécution plus rapide de 20% du code octet en ajoutant des méthodes inline, en supprimant les verrous inutilisés, etc. et en créant également le bytecode spécifique à cette machine. Je cite cet article, j'ai trouvé que c'était pratique. http://Java.dzone.com/articles/just-time-compiler-jit-hotspot

0
Santosh budhe

JIT fait référence au moteur d'exécution dans quelques implémentations de machine virtuelle, qui est plus rapide mais nécessite plus de mémoire. C'est un compilateur juste à temps. Dans ce schéma, les codes bytec d'une méthode sont compilés en code machine natif lors du premier appel de la méthode. Le code machine natif de la méthode est ensuite mis en cache afin qu'il puisse être réutilisé lors de l'appel suivant de la même méthode.