Initialisation des systèmes...

Baptiste.Dev
Retour aux notes
FondamentauxIntermédiaireSérie : Fondamentaux

Compilation vs interprétation

La synthèse : compilé ou interprété n'est pas noir ou blanc mais un spectre. AOT vs JIT, où se situe vraiment chaque langage (C/Rust, C#/Java, Python, JavaScript), et ce que ça change pour toi.

Par Baptiste Vidal
3 min de lecture
Mis à jour il y a 2 semaines
fondamentauxcompilationinterpretationjitaot

Compilation vs interprétation

On a vu séparément la compilation (tout traduire avant de lancer) et les langages interprétés (exécuter au fil de l'eau). Cette note fait la synthèse : en pratique, aucun langage moderne n'est tout blanc ou tout noir, et savoir où se situe le tien t'aide à comprendre ses forces et ses limites.


# La vraie question : QUAND traduit-on ?

« Compilé ou interprété ? » est une mauvaise question. La bonne, c'est : à quel moment le code devient-il du code machine, et combien de ce travail est fait à l'avance ?

  • À un extrême, tout est traduit avant de lancer : rapide à l'exécution, erreurs attrapées tôt.
  • À l'autre, tout est traduit pendant l'exécution : plus souple, démarrage immédiat, erreurs tardives.

La plupart des langages sont entre les deux. C'est un spectre, pas deux camps.


# AOT vs JIT

Deux stratégies pour ce « quand » :

  • AOT (Ahead-Of-Time) : toute la traduction en code machine est faite avant le lancement, une bonne fois. Résultat : un binaire natif prêt à courir, sans rien d'autre.
  • JIT (Just-In-Time) : la traduction en code machine se fait pendant l'exécution, au dernier moment, souvent guidée par ce qui tourne vraiment (le code « chaud » est optimisé en priorité).

Entre les deux, beaucoup de langages passent par une étape intermédiaire : ils compilent d'abord vers du bytecode (ni humain, ni machine), qu'un runtime finit ensuite en code machine par JIT.


# Où se situe chaque langage

LangageComment il tourne réellement
C, C++, RustCompilés AOT en binaire natif. Aucun runtime, au plus près de la machine.
GoCompilé AOT en binaire natif autonome (avec un petit runtime embarqué).
C#, JavaCompilés en bytecode (IL en .NET, bytecode JVM), puis JIT à l'exécution par le runtime (.NET / JVM).
Python, RubyCompilés en bytecode en interne, puis interprétés par une machine virtuelle.
JavaScriptInterprété puis JIT par le moteur (V8) : il démarre en interprétant, puis compile le code chaud à la volée.

Même les langages dits « interprétés » (Python) compilent en bytecode avant de l'exécuter. L'interprétation pure, ligne par ligne du texte source, est aujourd'hui très rare. Et l'inverse existe aussi : C# sait produire un binaire natif via Native AOT.


# Ce que ça change pour toi

CritèrePlutôt AOT / compilé natifPlutôt JIT / interprété
Erreursbeaucoup attrapées avant de lancer (dont les types)découvertes à l'exécution
Démarrageimmédiatle JIT doit « chauffer » un peu
Vitesse de pointetrès rapide, prévisiblele JIT peut optimiser finement le code chaud
Portabilitéliée à la plateforme (recompiler par OS/CPU)le bytecode + runtime tourne partout où le runtime existe
Distributionun binaire autonomebesoin du runtime/interpréteur ; le code source peut être visible

# À retenir

  • La vraie question n'est pas « compilé ou interprété » mais quand la traduction a lieu : c'est un spectre.
  • AOT : tout traduit avant, binaire natif (C, Rust, Go). JIT : traduit à l'exécution (C#, Java, JS), souvent via un bytecode.
  • Presque tous les langages « interprétés » compilent en bytecode en interne ; l'interprétation pure est rare.
  • Ce que ça change concrètement : quand les erreurs surgissent, le démarrage, la vitesse, la portabilité et la distribution.

À lire ensuite : La transpilation, une traduction d'un langage vers un autre, encore différente.