Que fait un compilateur juste à temps (JIT)?

Réponses:

518

Un compilateur JIT s'exécute après le démarrage du programme et compile le code (généralement du bytecode ou une sorte d'instructions de machine virtuelle) à la volée (ou juste à temps, comme on l'appelle) dans une forme qui est généralement plus rapide, généralement la native du CPU hôte jeu d'instructions. Un JIT a accès à des informations d'exécution dynamiques alors qu'un compilateur standard ne le fait pas et peut faire de meilleures optimisations telles que les fonctions intégrées qui sont fréquemment utilisées.

Cela contraste avec un compilateur traditionnel qui compile tout le code en langage machine avant la première exécution du programme.

Pour paraphraser, les compilateurs conventionnels construisent l'ensemble du programme en tant que fichier EXE AVANT la première fois que vous l'exécutez. Pour les programmes de style plus récents, un assembly est généré avec un pseudocode (p-code). Ce n'est qu'après avoir exécuté le programme sur le système d'exploitation (par exemple, en double-cliquant sur son icône) que le compilateur (JIT) démarrera et générera le code machine (m-code) que le processeur Intel ou autre comprendra.

Mark Cidade
la source
16
Et contrairement au code interprété, cela commence immédiatement à exécuter le bytecode ou les instructions VM, mais exécutera les instructions plus lentement que le langage machine.
Aaron
3
Un JIT est souvent utilisé avec du code interprété pour le convertir en langage machine mais oui, le code purement interprété (sans aucun JITting) est lent. Même le bytecode Java sans JITter est vraiment lent.
Mark Cidade
48
Cependant, la cible ne doit pas nécessairement être le code machine. JRuby a un compilateur JIT qui compilera le code source Ruby en bytecode Java après quelques appels. Ensuite, après un autre couple d'appels, le compilateur JVM JIT entre en action et compile le bytecode en code natif.
Jörg W Mittag
4
Il convient de noter que, comme le mentionne Jörg, JIT n'est pas nécessairement invoqué immédiatement. Souvent, le code sera interprété jusqu'à ce qu'il soit déterminé qu'il vaudra JITting. Étant donné que JITting peut introduire des retards, il peut être plus rapide de NE PAS JIT de code s'il est rarement utilisé et donc une réponse rapide est plus importante que l'exécution globale.
Adam Jaskiewicz
3
@ErikReppen: Si une nouvelle machine sort, la compilation et l'optimisation d'un programme pour cette nouvelle machine en utilisant un compilateur conventionnel donneront probablement des résultats plus rapides qu'un JIT. D'un autre côté, un JIT optimisé pour cette nouvelle machine sera en mesure d'optimiser les performances du code qui a été publié avant l'invention de cette nouvelle machine .
supercat
255

Au début, un compilateur était chargé de transformer un langage de haut niveau (défini comme un niveau supérieur à l'assembleur) en code objet (instructions machine), qui serait ensuite lié (par un éditeur de liens) en 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 a éliminé le code objet et les exécutables, et a permis à ces langages d'être portables sur plusieurs systèmes d'exploitation et plates-formes matérielles. Pascal (qui a compilé en 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 sont longues d'un octet.

Un compilateur Just-In-Time (JIT) est une fonctionnalité de l'interpréteur d'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 invoquera ceci code objet à la place. Idéalement, l'efficacité de l'exécution du code objet surmontera l'inefficacité de la recompilation du programme à chaque exécution.

Craig Trader
la source
5
Cependant, cette phrase «un compilateur Just-In-Time (JIT) est une fonctionnalité de l'interpréteur d'exécution» crée de la confusion; par exemple - stackoverflow.com/questions/16439512/…
Stephen C
11
En fait, le JIT était un module complémentaire, et vous pouvez toujours le désactiver en utilisant le paramètre -Xint pour Java, donc c'est juste une fonctionnalité.
Craig Trader
3
Je ne suis pas tout à fait d'accord. JIT n'est pas une évolution - c'est une alternative aux compilateurs classiques.
i486
1
JIT est une étape sur la voie évolutive des commutateurs mécaniques à câblage dur à la spécification des critères de recherche en disant "OK Google" à votre téléphone intelligent. Le JIT actuel disponible dans le cadre de Java 7/8 va au-delà de ce qui était disponible dans le cadre de Java 2 - c'est également une évolution.
Craig Trader du
1
@ i486 - Sun / Oracle (AFAIK) n'a jamais livré de compilateur classique ("en avance") pour Java qui génère du code natif. Il est exagéré de prétendre que JIT est une alternative ... quand ils pensent que c'est soi-disant une alternative pour n'a jamais été expédiée. (Je remets en cause le compilateur GCJ AOT car cela n'a rien à voir avec Sun / Oracle, et ce n'était pas non plus une solution complète. Il n'est certainement pas viable maintenant.)
Stephen C
69

JIT-Juste à temps le mot lui-même dit quand il 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 d'assemblage comme une 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 des codes requis sont uniquement convertis en code machine.

Comparaison JIT vs Non-JIT:

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

  • Comme le code machine sera généré lors de l'exécution ... le compilateur JIT produira un code machine optimisé pour exécuter l'architecture CPU de la machine.

Exemples JIT:

  1. En Java JIT est en 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 plus récentes.
Durai Amuthan.H
la source
7
JIT offre certains avantages spéciaux dans les frameworks avec prise en charge de types génériques réels; il est possible de définir une méthode générique qui serait capable de produire une gamme illimitée de types, chacun nécessiterait un code machine différent, mais le JIT ne générerait que du code pour les types qui sont réellement produits. En revanche, en C ++, il est nécessaire que le compilateur génère du code pour tous les types qu'un programme utilisera jamais.
supercat
6
La JVM ne code pas JIT la première fois qu'elle est exécutée. Les premières fois, il interprète le bytecode. Ensuite, si ce code s'exécute assez souvent, il peut décider de le déranger.
ninjalj
1
Vous dites que JIT en Java est JVM. Cependant, nous fournissons déjà le code compilé à JVM, n'est-ce pas? Ensuite, il le compile à nouveau, vous voulez dire?
Koray Tugay
@KorayTugay - Nous fournissons des Bytecodes à JVM et JVM en convertira une partie en code machine à la demande. Les ressources sont donc enregistrées.
Durai Amuthan.H
1
En Java, JIT n'est pas JVM. Cela n'en est qu'une partie.
happs
25

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, la JVM conserve un décompte du nombre de fois qu'une fonction est exécutée. Si ce nombre dépasse une limite prédéfinie, JIT compile le code en langage machine qui peut être directement exécuté par le processeur (contrairement au cas normal dans lequel javac compile le code en bytecode puis en java - l'interpréteur interprète ce bytecode ligne par ligne le convertit en code machine et s'exécute).

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 à nouveau interprété ligne par ligne. Cela rend l'exécution plus rapide.

Aniket Thakur
la source
14

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.

entrez la description de l'image ici

Sans compilateur JIT, l'interpréteur JVM traduit le code octet ligne par ligne pour le faire apparaître comme si une application native était en cours d'exécution.

entrez la description de l'image ici

La source


la source
1
Mon interprétation de JIT est qu'il agit comme la mémorisation, où les fonctions fréquemment utilisées sont «stockées» et les frais de compilation du bytecode java au code natif dépendant d'ISA sont contournés. Si c'est correct, pourquoi java ne compile-t-il pas complètement en code natif depuis le début? Cela réduirait toute sorte de compilation au moment de l'exécution et rendrait Java «natif» sur la machine?
Michael Choi
12

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

Ceci est bénéfique 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.

Brian Lyttle
la source
Pourquoi les codes compilés ne sont-ils pas stockés quelque part dans l'ordinateur de l'utilisateur, donc la prochaine fois que l'application sera exécutée, JIT n'aura pas à les recompiler à nouveau?
omerfarukdogan
Bonnes observations. Il est possible de le faire, mais son efficacité dépend de la plate-forme et de l'utilisation de l'application. L'optimisation JIT n'est pas nécessairement la même que l'optimisation hors ligne ou à l'avance, de sorte que l'avantage ne peut être que «pas JITting», ce qui peut ou peut ne pas aider beaucoup.
Brian Lyttle
9

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 JVM (en Java). Le code d'octet sera chargé dans JVM par le chargeur, puis chaque instruction d'octet sera interprétée.

Lorsque nous devons appeler une méthode plusieurs fois, nous devons interpréter le même code plusieurs fois et cela peut prendre plus de temps que nécessaire. Nous avons donc les compilateurs JIT (juste à temps). Lorsque l'octet a été chargé dans JVM (son temps d'exécution), le code entier sera 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 pas de sortie binaire.

Utilisateur
la source
2
Le code entier n'est pas compilé lorsqu'il est chargé dans la JVM, car il y a peu d'informations (lire: guide) sur la façon de procéder à la compilation. Gardez à l'esprit que la performance est le but ultime. JIT est plutôt sélectif: surveiller et sélectionner les méthodes d'optimisation les plus courantes. Et cela continue jusqu'à ce que le niveau maximal d'optimisation soit atteint pour les méthodes individuelles.
Yaw Boakye
7

Compilateur Just In Time (JIT):
il compile les bytecodes java 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 s'exécute 10 fois si la valeur de i est 0.

Il n'est pas nécessaire de compiler le bytecode 10 fois encore et encore car la même instruction va s'exécuter 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. Ainsi, le compilateur Just In Time (JIT) assure le suivi de ces instructions et méthodes (comme indiqué ci-dessus) et compile ces morceaux de code octet en code machine pour de meilleures performances.

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

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

Consultez cette documentation Oracle sur Comprendre JIT pour en savoir plus.

Anands23
la source
"Il n'est pas nécessaire de compiler le bytecode 10 fois encore et encore car la même instruction va s'exécuter 10 fois" - qu'en est-il d'un compilateur normal? Compile-t-il cette pièce plusieurs fois?
TT_
4

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

Charles Graham
la source
2
Que voulez-vous dire par "niveau de méthode"?
Koray Tugay
4

Je sais que c'est un vieux fil, mais l'optimisation de l'exécution est une autre partie importante de la compilation JIT qui ne semble pas être discutée 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 de Google JIT (javaworld a un très bon article à ce sujet. )

eze
la source
3

Un compilateur juste à temps (JIT) est un logiciel qui prend 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 de ceci est que pour une certaine architecture CPU, 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. Compilateur : prend le code source et retourne un exécutable
  2. Interprète : exécute l'instruction du programme 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é en instructions machine et exécuté.
  3. JIT : De nombreuses implémentations différentes d'un JIT sont possibles, mais un JIT est généralement une combinaison d'un compilateur et d'un interpréteur. Le JIT transforme d'abord les données intermédiaires (par exemple le bytecode Java) qu'il reçoit en langage machine via l'interprétation. Un JIT peut souvent détecter quand une certaine partie du code est exécutée souvent et le compilera pour une exécution plus rapide.
Willem van der Veen
la source
2

Jit signifie juste à temps compilateur jit est un programme qui transforme le code d'octet java en instruction qui peut être envoyée directement au processeur.

L'utilisation du compilateur java juste à temps (en fait un deuxième compilateur) sur la plate-forme système particulière conforme le bytecode dans un code système particulier, une fois que le code a été recompilé par le compilateur jit, il s'exécutera généralement plus rapidement sur l'ordinateur.

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

user3459027
la source
2

La compilation juste à temps (JIT), (également traduction dynamique ou compilation au moment de l'exécution ), est un moyen d'exécuter du code informatique qui implique la compilation pendant 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 des deux approches traditionnelles de la traduction en code machine - la compilation anticipée (AOT) et l' interprétation - et combine certains avantages et inconvénients des deux. La compilation JIT combine la vitesse du code compilé avec la flexibilité 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 pendant que l'application Java est en cours d'exécution et génèrent des instructions de machine native hautes performances ciblées pour l'architecture système sous-jacente.

Lorsqu'une méthode est choisie pour la compilation, la JVM transmet son bytecode au compilateur Just-In-Time (JIT). Le JIT doit comprendre la sémantique et la syntaxe du bytecode avant de pouvoir compiler correctement la méthode. Pour aider le compilateur JIT à analyser la méthode, son bytecode est d'abord reformulé dans une représentation interne appelée arbres de trace, qui ressemble plus au code machine que le bytecode. L'analyse et les optimisations sont ensuite effectuées sur les arbres de la méthode. À la fin, les arbres sont traduits en code natif.

Un arbre de trace est une structure de données utilisée dans la compilation d'exécution du code de programmation. Les arbres de trace sont utilisés dans un type de «compilateur juste à temps» qui trace l'exécution du code pendant les points chauds et le compile. Référez ceci .

Référer :

premier
la source
1

Un compilateur non JIT prend le code source et le transforme en code octet spécifique à la machine au moment de la compilation. Un compilateur JIT prend le code d'octet indépendant de la machine qui a été généré au moment de la compilation et le transforme en code d'octet spécifique à la machine au moment de l'exécution. Le compilateur JIT que Java utilise est ce qui permet à un seul binaire de s'exécuter sur une multitude de plateformes sans modification.


la source
0

20% du code d'octet est utilisé 80% du temps. Le compilateur JIT obtient ces statistiques et optimise ces 20% du code d'octets pour s'exécuter plus rapidement en ajoutant des méthodes en ligne, 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

Santosh budhe
la source
Je ne sais pas pourquoi cela a été marqué -1. Je pense que le point ici est que les statistiques d'exécution sont utilisées pour aider à optimiser.
eze
Oui, mais la réponse ne l'a pas formulé ainsi. Littéralement, JIT n'optimise pas les 20% les plus chauds du code.
mabraham
0

JIT fait référence au moteur d'exécution dans quelques implémentations JVM, qui est plus rapide mais nécessite plus de mémoire, est un compilateur juste à temps. Dans ce schéma, les bytecodes d'une méthode sont compilés en code machine natif la première fois que la méthode est invoquée. Le code machine natif de la méthode est ensuite mis en cache, il peut donc être réutilisé la prochaine fois que la même méthode est invoquée.

Venkata Santhosh Piduri
la source
2
J'éviterais de répondre à une question comme celle-ci si vous ne fournissez pas quelque chose de nouveau / meilleur. Si vous obtenez une réaction, c'est probablement un downvote ou une critique: votre réponse est imprécise. "JIT" n'est pas limité à une machine virtuelle Java , "plus rapide mais utilise plus de mémoire" est un effet probable mais non inhérent au concept JIT, et les méthodes ne sont souvent pas compilées lors de la première invocation, plutôt après plusieurs lorsqu'il devient clair que le temps passé sur JIT'ing est globalement avantageux.
zapl
0

La JVM effectue en fait des étapes de compilation pendant l'exécution pour des raisons de performances. Cela signifie que Java n'a pas de séparation de compilation-exécution propre. Il fait d'abord une soi-disant compilation statique du code source Java au bytecode. Ensuite, ce bytecode est transmis à la JVM pour exécution. Mais l'exécution du bytecode est lente, donc la JVM mesure la fréquence d'exécution du bytecode et lorsqu'elle détecte un "hotspot" de code qui est exécuté très fréquemment, elle effectue une compilation dynamique du bytecode au machinecode du code "hotspot" (hotspot profiler). Si efficacement aujourd'hui, les programmes Java sont exécutés par l'exécution de code machine.

hi.nitish
la source
0

Le compilateur Just In Time, également appelé compilateur JIT, est utilisé pour améliorer les performances en Java. Il est activé par défaut. Il s'agit d'une compilation effectuée au moment de l'exécution plutôt plus tôt. Java a popularisé l'utilisation du compilateur JIT en l'incluant dans JVM.

Ganesh Giri
la source