Explication de la compilation juste à temps

La compilation juste à temps est une méthode pour améliorer les performances des programmes interprétés. Pendant l'exécution, le programme peut être compilé en code natif pour améliorer ses performances. Il est également connu sous le nom de compilation dynamique.

La compilation dynamique présente certains avantages par rapport à la compilation statique. Lors de l'exécution d'applications Java ou C #, l'environnement d'exécution peut profiler l'application pendant son exécution. Cela permet de générer un code plus optimisé. Si le comportement de l'application change pendant son exécution, l'environnement d'exécution peut recompiler le code.

Certains des inconvénients comprennent les délais de démarrage et la surcharge de compilation pendant l'exécution. Pour limiter la surcharge, de nombreux compilateurs JIT ne compilent que les chemins de code fréquemment utilisés.

Aperçu

Traditionnellement, il existe deux méthodes pour convertir le code source dans un formulaire qui peut être exécuté sur une plate-forme. La compilation statique convertit le code dans un langage pour une plate-forme spécifique. Un interpréteur exécute directement le code source.

La compilation JIT tente d'utiliser les avantages des deux. Pendant l'exécution du programme interprété, le compilateur JIT détermine le code le plus fréquemment utilisé et le compile en code machine. Selon le compilateur, cela peut être fait sur une méthode ou une plus petite section de code.

La compilation dynamique a été décrite pour la première fois dans un article de J. McCarthy sur LISP en 1960.

Just In Time Compilation, JIT, ou Dynamic Translation, est une compilation effectuée pendant l'exécution d'un programme. Signification, au moment de l'exécution, par opposition à avant l'exécution. Ce qui se passe, c'est la traduction en code machine. Les avantages d'un JIT sont dus au fait que, puisque la compilation a lieu au moment de l'exécution, un compilateur JIT a accès à des informations dynamiques d'exécution lui permettant de faire de meilleures optimisations (comme les fonctions d'inlining).

Ce qu'il est important de comprendre à propos de la compilation JIT, c'est qu'elle compilera le bytecode en instructions de code machine de la machine en cours d'exécution. Cela signifie que le code machine résultant est optimisé pour l'architecture CPU de la machine en cours d'exécution.

Quelques exemples de compilateurs JIT sont JVM (Java Virtual Machine) en Java et CLR (Common Language Runtime), en C #.

Histoire

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) à un exécutable.

À un moment donné 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, puisque 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 appelée, compilera le bytecode dans les instructions de code machine de la machine en cours d'exécution, puis invoquera 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.

Scénario typique

Le code source est entièrement converti en code machine

Scénario JIT

Le code source sera converti en langage assembleur 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 des codes requis ne sont convertis qu'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, ce qui réduit la 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 l'exécution de l'architecture CPU de la machine.

Quelques exemples de JIT sont:

  • Java: JVM (machine virtuelle Java)
  • C #: CLR (Common Language Runtime)
  • Android: DVM (Dalvik Virtual Machine) ou ART (Android RunTime) dans les versions plus récentes

La machine virtuelle Java (JVM) exécute le bytecode et tient à jour le nombre d'exécutions d'une fonction. 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 Java, l'interpréteur interprète ce bytecode ligne par ligne le convertit en code machine et exécute).

Aussi 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.