web-dev-qa-db-fra.com

Langages compilés et interprétés

J'essaie de mieux comprendre la différence. J'ai trouvé beaucoup d'explications en ligne, mais elles tendent aux différences abstraites plutôt qu'aux implications pratiques.

La plupart de mes expériences de programmation ont été avec CPython (dynamique, interprété) et Java (statique, compilé). Cependant, je comprends qu’il existe d’autres types de langages interprétés et compilés. Outre le fait que les fichiers exécutables peuvent être distribués à partir de programmes écrits dans des langages compilés, existe-t-il des avantages/inconvénients pour chaque type? Souvent, j'entends des personnes dire que les langages interprétés peuvent être utilisés de manière interactive, mais je pense que les langages compilés peuvent également avoir des implémentations interactives, n'est-ce pas?

258
chimeracoder

Un langage compilé est un langage dans lequel le programme, une fois compilé, est exprimé dans les instructions de la machine cible. Par exemple, une opération "+" dans votre code source peut être traduite directement dans l'instruction "ADD" du code machine.

Un langage interprété est un langage dans lequel les instructions ne sont pas directement exécutées par la machine cible, mais lues et exécutées par un autre programme (normalement est écrit dans la langue de la machine native). Par exemple, la même opération "+" serait reconnue par l'interpréteur lors de l'exécution, qui appellerait alors sa propre fonction "add (a, b)" avec les arguments appropriés, qui exécuterait ensuite l'instruction "ADD" de code machine. .

Vous pouvez faire tout ce que vous pouvez faire dans un langage interprété dans un langage compilé et inversement - ils sont tous deux complets. Les deux présentent toutefois des avantages et des inconvénients pour la mise en œuvre et l'utilisation.

Je vais généraliser complètement (les puristes me pardonnent!) Mais, grosso modo, voici les avantages des langages compilés:

  • Performances plus rapides en utilisant directement le code natif de la machine cible
  • Possibilité d'appliquer des optimisations assez puissantes lors de la compilation

Et voici les avantages des langages interprétés:

  • Plus facile à implémenter (écrire de bons compilateurs est très difficile !!)
  • Pas besoin de lancer une phase de compilation: peut exécuter du code directement "à la volée"
  • Peut être plus pratique pour les langages dynamiques

Notez que les techniques modernes, telles que la compilation de code intermédiaire, ajoutent une complexité supplémentaire. Ce qui se passe ici, c'est que le compilateur cible une "machine virtuelle" qui n'est pas identique au matériel sous-jacent. Ces instructions de machine virtuelle peuvent ensuite être à nouveau compilées ultérieurement pour obtenir du code natif (par exemple, comme le fait le compilateur JVM JIT Java.).

430
mikera

Un langage lui-même n'est ni compilé ni interprété, seule une implémentation spécifique d'un langage l'est. Java est un exemple parfait. Il existe une plate-forme à code-octets (la machine virtuelle Java), un compilateur natif (gcj) et un interpéter pour un sur-ensemble de Java (bsh). Alors, qu'est-ce que Java maintenant? Compilé en bytecode, compilé en natif ou interprété?

Les autres langages, compilés et interprétés, sont le scala, le haskell ou l’ocaml. Chacune de ces langues possède un interpréteur interactif, ainsi qu'un compilateur en code octet ou en code machine natif.

Donc, classer les langues par "compilé" et "interprété" n'a généralement aucun sens.

94
lunaryorn

Commencez à penser en termes de: souffle du passé

Il était une fois, il y a très longtemps, le royaume des interprètes et des compilateurs informatiques. Toutes sortes de discussions se sont ensuivies sur les mérites de l'un sur l'autre. L’opinion générale à cette époque ressemblait à quelque chose comme:

  • Interprète: Rapide à développer (éditer et exécuter). Lent à exécuter car chaque instruction devait être interprétée dans le code machine à chaque exécution (pensez à ce que cela signifiait pour une boucle exécutée des milliers de fois).
  • Compilateur: Lent à développer (éditer, compiler, lier et exécuter. Les étapes de compilation/lier pourraient prendre beaucoup de temps). Rapide à exécuter. L'ensemble du programme était déjà en code machine natif.

Une différence d'un ou deux ordres de grandeur dans les performances d'exécution existait entre un programme interprété et un programme compilé. D'autres points distinctifs, la mutabilité du code au moment de l'exécution, par exemple, présentaient également un intérêt, mais la principale distinction concernait les problèmes de performances au moment de l'exécution.

Aujourd'hui, le paysage a tellement évolué que la distinction compilé/interprété est à peu près sans importance. De nombreux langages compilés font appel à des services d'exécution qui ne sont pas entièrement basés sur du code machine. En outre, la plupart des langages interprétés sont "compilés" en code octet avant exécution. Les interprètes de code octet peuvent être très efficaces et rivaliser avec le code généré par le compilateur du point de vue de la vitesse d'exécution.

La différence classique est que les compilateurs ont généré du code machine natif, les interprètes ont lu le code source et le code machine généré à la volée à l’aide d’une sorte de système d’exécution. Aujourd'hui, il ne reste que très peu d'interprètes classiques - la quasi-totalité d'entre eux sont compilés en code octet (ou dans un autre état semi-compilé) qui s'exécute ensuite sur une "machine" virtuelle.

50
NealB

Les cas extrêmes et simples:

  • Un compilateur produira un exécutable binaire au format d'exécutable natif de la machine cible. Ce fichier binaire contient toutes les ressources requises, à l'exception des bibliothèques système. il est prêt à fonctionner sans autre préparation ni traitement et fonctionne comme un éclair, car le code est le code natif de la CPU sur la machine cible.

  • Un interprète présentera à l’utilisateur une invite dans une boucle dans laquelle il pourra entrer des instructions ou du code. Lorsqu’il appuiera sur RUN ou l’équivalent, l’interprète examinera, analysera, analysera et exécutera chaque ligne jusqu’à ce que le programme soit exécuté. point d'arrêt ou une erreur. Étant donné que chaque ligne est traitée séparément et que l'interprète n'apprend rien après avoir vu la ligne auparavant, l'effort de conversion d'un langage lisible par un humain en instructions machine s'exerce à chaque fois pour chaque ligne; il est donc lent. Du bon côté des choses, l’utilisateur peut inspecter son programme et interagir avec celui-ci de différentes manières: modification de variables, modification de code, exécution en mode trace ou débogage, peu importe.

Avec ceux qui sont à l’écart, laissez-moi vous expliquer que la vie n’est plus aussi simple. Par exemple,

  • De nombreux interprètes pré-compileront le code qui leur est donné afin que l'étape de traduction n'ait pas à être répétée encore et encore.
  • Certains compilateurs ne compilent pas en instructions machine spécifiques au processeur, mais en bytecode, une sorte de code machine artificiel pour une machine fictive. Cela rend le programme compilé un peu plus portable, mais nécessite un interpréteur de bytecode sur chaque système cible.
  • Les interpréteurs de bytecode (je regarde Java ici) ont récemment tendance à recompiler le bytecode qu'ils obtiennent pour le CPU de la section cible juste avant l'exécution (appelé JIT). Pour gagner du temps, cela n'est souvent fait que pour le code qui tourne souvent (points chauds).
  • Certains systèmes qui ressemblent à des interprètes (Clojure, par exemple) compilent immédiatement le code qu'ils obtiennent, tout en permettant un accès interactif à l'environnement du programme. C'est essentiellement la commodité des interprètes avec la rapidité de la compilation binaire.
  • Certains compilateurs ne compilent pas vraiment, ils pré-digèrent et compressent le code. J'ai entendu dire il y a quelque temps que Perl fonctionne. Donc, parfois, le compilateur fait juste un peu du travail et la plus grande partie reste de l'interprétation.

Au final, ces jours-ci, interpréter ou compiler est un compromis, le temps passé à compiler (une fois) étant souvent récompensé par de meilleures performances à l'exécution, mais un environnement interprétatif offrant davantage de possibilités d'interaction. Compiler ou interpréter dépend principalement de la façon dont le travail de "compréhension" du programme est divisé en différents processus, et la ligne est un peu floue ces temps-ci, car les langages et les produits tentent d'offrir le meilleur des deux mondes.

24
Carl Smotricz

De http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages

Il n’ya pas de différence, car "langage de programmation compilé" et "langage de programmation interprété" ne sont pas des concepts significatifs. Tous les langages de programmation, et je veux dire tous les, peuvent être interprétés ou compilés. Ainsi, l'interprétation et la compilation sont des techniques de mise en œuvre, pas des attributs de langages.

L'interprétation est une technique par laquelle un autre programme, l'interprète, effectue des opérations pour le compte du programme en cours d'interprétation afin de l'exécuter. Si vous pouvez imaginer lire un programme et faire ce qu’il dit pour le faire étape par étape, par exemple sur un bout de papier brouillon, c’est exactement ce que fait un interprète. Une raison commune d'interpréter un programme est que les interprètes sont relativement faciles à écrire. Une autre raison est qu'un interprète peut surveiller ce qu'un programme tente de faire en cours d'exécution, pour appliquer une stratégie, par exemple, de sécurité.

La compilation est une technique par laquelle un programme écrit dans une langue (la "langue source") est traduit en un programme dans une autre langue (le "langage objet"), ce qui signifie, espérons-le, la même chose que le programme original. Lors de la traduction, il est courant que le compilateur tente également de transformer le programme de manière à rendre le programme objet plus rapide (sans en changer le sens!). Une raison commune pour compiler un programme est qu’il existe un bon moyen d’exécuter des programmes dans le langage objet, sans la surcharge d’interprétation du langage source en cours de route.

Vous avez peut-être deviné, sur la base des définitions ci-dessus, que ces deux techniques de mise en œuvre ne s'excluent pas mutuellement et peuvent même être complémentaires. Traditionnellement, le langage objet d'un compilateur était un code machine ou quelque chose de similaire, qui fait référence à un nombre quelconque de langages de programmation compris par des processeurs d'ordinateur particuliers. Le code machine fonctionnerait alors "sur le métal" (bien que l'on puisse voir, si on y regarde de trop près, que le "métal" fonctionne beaucoup comme un interprète). Aujourd'hui, cependant, il est très courant d'utiliser un compilateur pour générer du code objet destiné à être interprété. Par exemple, c'est ainsi que Java fonctionne (et fonctionne parfois encore). Il existe des compilateurs qui traduisent d'autres langages en JavaScript, qui est ensuite souvent exécuté dans un navigateur Web, ce qui peut interpréter le JavaScript ou le compiler en machine virtuelle ou en code natif. Nous avons également des interprètes pour le code machine, qui peuvent être utilisés pour émuler un type de matériel sur un autre. Ou bien, on peut utiliser un compilateur pour générer un code objet qui est ensuite le code source d'un autre compilateur, qui peut même compiler du code en mémoire juste à temps pour qu'il s'exécute, lequel à son tour. . . vous avez eu l'idée. Il existe de nombreuses façons de combiner ces concepts.

20
Bhavin Shah

Le principal avantage du code source interprété par rapport au code source compilé est PORTABILITY.

Si votre code source est compilé, vous devez compiler un exécutable différent pour chaque type de processeur et/ou de plate-forme sur laquelle vous souhaitez exécuter votre programme (par exemple, un pour Windows x86, un pour Windows x64, un pour Linux x64, etc.). sur). En outre, à moins que votre code ne soit totalement conforme aux normes et n'utilise aucune fonction/bibliothèque spécifique à la plate-forme, vous devrez réellement écrire et gérer plusieurs bases de code!

Si votre code source est interprété, il vous suffit de l'écrire une seule fois et il peut être interprété et exécuté par un interpréteur approprié sur n'importe quelle plate-forme! C'est portable! Notez qu'un interprète lui-même est un programme exécutable qui est écrit et compilé pour une plate-forme spécifique.

Un avantage du code compilé est qu’il cache le code source de l’utilisateur final (ce qui pourrait être propriété intellectuelle) car au lieu de déployer le code source lisible par l’homme original, vous déployer un obscur fichier exécutable binaire.

10
Niko Bellic

Un compilateur et un interprète font le même travail: traduire un langage de programmation dans un autre langage de lecture, généralement plus proche du matériel, souvent dans un code machine exécutable.

Traditionnellement, "compilé" signifie que cette traduction se fait en une fois, est effectuée par un développeur et que l'exécutable résultant est distribué aux utilisateurs. Exemple pur: C++. La compilation prend généralement beaucoup de temps et essaie de faire beaucoup d’optimisation coûteuse afin que l’exécutable résultant fonctionne plus rapidement. Les utilisateurs finaux ne disposent ni des outils ni des connaissances pour compiler eux-mêmes des éléments et l'exécutable doit souvent s'exécuter sur divers matériels. Vous ne pouvez donc pas effectuer de nombreuses optimisations spécifiques. Au cours du développement, l’étape de compilation séparée signifie un cycle de rétroaction plus long.

Traditionnellement, "interprété" signifie que la traduction a lieu "à la volée", lorsque l'utilisateur souhaite exécuter le programme. Exemple pur: PHP vanille. Un interprète naïf doit analyser et traduire chaque morceau de code à chaque exécution, ce qui le rend très lent. Des optimisations complexes et coûteuses ne peuvent pas être réalisées, car elles prendraient plus de temps que le gain de temps d'exécution. Mais il peut pleinement utiliser les capacités du matériel sur lequel il tourne. L'absence d'une étape de compilation distincte réduit le temps de réponse pendant le développement.

Mais de nos jours, "compilé vs interprété" n'est pas un problème noir ou blanc, il y a des nuances entre les deux. Les interprètes naïfs et simples sont quasiment éteints. De nombreuses langues utilisent un processus en deux étapes dans lequel le code de haut niveau est traduit en un bytecode indépendant de la plate-forme (dont l'interprétation est beaucoup plus rapide). Ensuite, vous avez des "compilateurs" juste à temps "qui compilent le code au plus une fois par programme exécuté, mettent parfois en cache les résultats et décident même intelligemment d’interpréter du code qui est exécuté rarement, et effectuent de puissantes optimisations pour le code qui tourne beaucoup. Pendant le développement, les débogueurs sont capables de changer de code dans un programme en cours, même pour les langages compilés de manière traditionnelle.

7
Michael Borgwardt

Tout d’abord, une clarification, Java n’est pas complètement compilé de façon statique ni lié de la même manière que C++. Il est compilé en bytecode, qui est ensuite interprété par une machine virtuelle Java. La machine virtuelle Java peut effectuer une compilation juste à temps dans le langage machine natif, mais ne doit pas nécessairement le faire.

Plus précisément, je pense que l’interactivité est la principale différence pratique. Puisque tout est interprété, vous pouvez prendre un petit extrait de code, l’analyser et le lancer en fonction de l’état actuel de l’environnement. Ainsi, si vous aviez déjà exécuté du code qui initialisait une variable, vous auriez accès à cette variable, etc. Cela se prête vraiment à des choses comme le style fonctionnel.

L’interprétation coûte toutefois très cher, surtout lorsque vous avez un grand système avec beaucoup de références et de contexte. Par définition, cela représente un gaspillage, car un code identique doit parfois être interprété et optimisé deux fois (bien que la plupart des environnements d’exécution aient une mise en cache et des optimisations pour cela). Néanmoins, vous payez un coût d’exécution et avez souvent besoin d’un environnement d’exécution. Vous êtes également moins susceptible de voir des optimisations interprocédurales complexes car, à l'heure actuelle, leurs performances ne sont pas suffisamment interactives.

Par conséquent, pour les grands systèmes qui ne vont pas beaucoup changer et pour certaines langues, il est plus logique de tout précompiler et de créer des liaisons préalables, de faire toutes les optimisations que vous pouvez faire. Cela aboutit à un runtime très maigre déjà optimisé pour la machine cible.

Quant à la génération d’exécutables, cela a peu à voir avec cela, à mon humble avis. Vous pouvez souvent créer un exécutable à partir d'un langage compilé. Mais vous pouvez également créer un exécutable à partir d'un langage interprété, à la différence que l'interpréteur et le moteur d'exécution sont déjà empaquetés dans l'exécutable et cachés de votre part. Cela signifie que vous payez généralement toujours les coûts d’exécution (bien que je suis sûr que pour certaines langues, il existe des moyens de tout traduire en un exécutable arborescent).

Je ne suis pas d'accord pour dire que toutes les langues pourraient devenir interactives. Certains langages, tels que C, sont tellement liés à la machine et à la structure de liens que je ne suis pas sûr que vous puissiez créer une version interactive complète à part entière.

4
Uri

Le livre Python © 2015 Imagine Publishing Ltd, illustre simplement la différence par le conseil suivant mentionné à la page 10:

Un langage interprété tel que Python est un langage dans lequel le code source est converti en code machine, puis exécuté à chaque exécution du programme. Ceci diffère d'un langage compilé tel que C, où le code source n'est converti qu'une seule fois en code machine. Le code machine résultant est ensuite exécuté à chaque exécution du programme.

2
Ahmed Shaban Helwa

Il est plutôt difficile de donner une réponse pratique car la différence concerne la définition du langage lui-même. Il est possible de créer un interpréteur pour chaque langage compilé, mais il n'est pas possible de créer un compilateur pour chaque langage interprété. Cela concerne beaucoup la définition formelle d'une langue. Donc, ce genre d’informatique théorique que personne n’aime à l’université.

2
Steven Mohr

Compiler est le processus de création d'un programme exécutable à partir de code écrit dans un langage de programmation compilé. La compilation permet à l'ordinateur d'exécuter et de comprendre le programme sans avoir besoin du logiciel de programmation utilisé pour le créer. Lorsqu'un programme est compilé, il est souvent compilé pour une plate-forme spécifique (plate-forme IBM, par exemple) fonctionnant avec des ordinateurs compatibles IBM, mais pas avec d'autres plates-formes (ex: plate-forme Apple). Le premier compilateur a été développé par Grace Hopper alors qu’il travaillait sur l’ordinateur Mark I de Harvard. Aujourd'hui, la plupart des langages de haut niveau incluent leur propre compilateur ou disposent de kits d'outils pouvant être utilisés pour compiler le programme. Eclipse est un bon exemple de compilateur utilisé avec Java et un exemple de compilateur utilisé avec C et C++ est la commande gcc. Selon la taille du programme, la compilation devrait prendre quelques secondes ou quelques minutes. Si aucune erreur n’est détectée lors de la compilation, un fichier exécutable est créé. Vérifiez ces informations.

1
salehvm

Différences

Interprète:

1) Processus: Un interprète produit un résultat d'un programme. (Convertit le programme en code machine lorsque le programme est exécuté) Dans un programme interprété, par contre, le code source est généralement le programme. Les programmes de ce type (souvent appelés scripts) nécessitent un interpréteur, qui analyse les commandes du programme puis les exécute. Certains interprètes, tels que les shells Unix (sh, csh, ksh, etc.) lisent et exécutent immédiatement chaque commande, tandis que d'autres, tels que Perl, analysent l'intégralité du script avant d'envoyer les instructions en langage machine correspondantes. JavaScript et Python sont d’autres exemples de langage interprété.

2) Rapide à développer (éditer et exécuter).

3) Lent à exécuter car chaque instruction devait être interprétée dans le code machine à chaque exécution (pensez à ce que cela signifiait pour une boucle exécutée des milliers de fois).

4) Si votre code source est interprété, il vous suffit de l'écrire une seule fois et il peut être interprété et exécuté par un interpréteur approprié sur n'importe quelle plate-forme!

5) L’un des inconvénients de l’interpréteur est qu’il ne cache pas le code source à l’utilisateur final.

6) Continue à traduire le programme jusqu'à ce que la première erreur soit rencontrée, auquel cas elle s'arrête. Par conséquent, le débogage est facile.

Compilateur:

1) Processus: (Convertit le programme en code machine avant son exécution) pendant qu’un compilateur produit un programme écrit en langage Assembly. L'assembleur d'architecture transforme ensuite le programme résultant en code binaire. Le langage d'assemblage varie pour chaque ordinateur, en fonction de son architecture. Par conséquent, les programmes compilés ne peuvent s'exécuter que sur des ordinateurs dotés de la même architecture que l'ordinateur sur lequel ils ont été compilés. Un programme compilé n'est pas lisible par l'homme, mais se trouve dans un langage machine spécifique à l'architecture. La création d'un programme compilé nécessite plusieurs étapes. Tout d'abord, le programmeur, à l'aide d'un outil de développement ou même d'un simple éditeur de texte, écrit le code source dans un langage informatique choisi. Si le programme est complexe, des morceaux de celui-ci peuvent être répartis sur plusieurs fichiers. Le programmeur compile ensuite le programme en triant et reliant les modules et en traduisant le tout en un code machine que l'ordinateur comprend. Étant donné que différents types d’ordinateurs ne parlent pas les langages informatiques les uns des autres, un programme compilé ne fonctionne que sur la plate-forme pour laquelle il a été conçu. Par exemple, un programme écrit pour HP-UX ne fonctionnera normalement pas sur un ordinateur Mac OS ou sur un ordinateur exécutant Solaris.

2) Lent à développer (éditer, compiler, lier et exécuter. Les étapes de compilation/lier pourraient prendre beaucoup de temps).

3) Rapide à exécuter. L'ensemble du programme était déjà en code machine natif.

4) Le programme compilé ne fonctionnera que sur la plate-forme pour laquelle il a été conçu. Ce n'est pas portable

5) Un avantage du code compilé est qu'il cache le code source à l'utilisateur final (ce qui peut être une propriété intellectuelle) car au lieu de déployer le code source lisible par l'homme d'origine, vous déployez un obscur fichier exécutable binaire. 6) Il génère le message d'erreur uniquement après avoir analysé l'ensemble du programme. Par conséquent, le débogage est relativement difficile.

Sources: * https://kb.iu.edu/d/agsz * Réponses différentes dans cet article

0
abc123