250 votes

Le langage de la "machine virtuelle" de Java et de l'"interpréteur" de Python ?

Il semble rare de lire un article sur une "machine virtuelle" en Python, alors qu'en Java, le terme "machine virtuelle" est utilisé en permanence.

Tous deux interprètent des codes d'octets ; pourquoi appeler l'un une machine virtuelle et l'autre un interprète ?

198voto

Poor Yorick Points 9

Dans ce billet, le terme "machine virtuelle" fait référence aux machines virtuelles de processus, et non aux machines virtuelles de système comme Qemu ou Virtualbox. machines virtuelles système comme Qemu ou Virtualbox. Une machine virtuelle de processus est simplement un programme qui fournit un environnement de programmation général -- un programme qui peut être programmé.

Java a un interpréteur ainsi qu'une machine virtuelle, et Python a une machine virtuelle ainsi qu'un interpréteur. virtuelle et d'un interprète. La raison pour laquelle "machine virtuelle" est un terme plus est un terme plus courant en Java et que "interprète" est un terme plus courant en Python a beaucoup a beaucoup à voir avec la différence majeure entre les deux langages : le typage statique (Java) et le typage dynamique (Python). Dans ce contexte, le terme "type" fait référence à types de données primitives -- types qui suggèrent la taille de stockage en mémoire des données. La machine virtuelle Java a la tâche facile. Elle exige du programmeur qu'il spécifie le type de données primitif de chaque variable. Cela fournit suffisamment informations suffisantes pour que le bytecode Java soit interprété et exécuté par la machine virtuelle Java. machine virtuelle Java, mais aussi pour être compilé en instructions machine . La machine virtuelle Python est plus complexe dans le sens où elle prend en charge la tâche supplémentaire qui consiste à faire une pause avant l'exécution de chaque opération afin de déterminer si la machine virtuelle a bien été exécutée. tâche supplémentaire qui consiste à faire une pause avant l'exécution de chaque opération pour déterminer les types de données primitifs de chaque variable ou structure de données impliquée dans l'opération. opération. Python libère le programmeur de la nécessité de penser en termes de types de données primitives. et permet d'exprimer les opérations à un niveau supérieur. Le prix de cette cette liberté est la performance. "Interprète" est le terme préféré pour Python parce qu'il doit faire une pause pour inspecter les types de données, et aussi parce que la syntaxe relativement concise des langages à typage dynamique convient bien aux interfaces interactives. interfaces interactives. Il n'y a pas de barrière technique à la construction d'une interface interactive en Java. interactive en Java, mais essayer d'écrire un code statiquement typé de manière interactive serait fastidieux, c'est pourquoi il n'est pas fait de cette façon.

Dans le monde Java, la machine virtuelle vole la vedette parce qu'elle exécute des programmes écrits dans un langage qui peut être compilé en instructions machine, et le résultat est la vitesse et l'efficacité des ressources. Le bytecode Java peut être exécuté par la machine virtuelle Java avec des performances proches de celles des programmes compilés. compilés, relativement parlant. Cela est dû à la présence d'informations sur les types de données primitives dans le bytecode. de données primitives dans le bytecode. La machine virtuelle Java place Java dans une catégorie à part :

langage interprété portable à typage statique

Ce qui s'en rapproche le plus est LLVM, mais LLVM opère à un niveau différent :

langage assembleur interprété portable

Le terme " bytecode " est utilisé à la fois en Java et en Python, mais tous les bytecodes ne sont pas égaux. Le bytecode est simplement le terme générique pour les langages intermédiaires utilisés par les ordinateurs. utilisés par les compilateurs/interprètes. Même les compilateurs C comme gcc utilisent un code intermédiaire langue (ou plusieurs) pour faire le travail. Le bytecode Java contient des informations sur les types de données primitifs, alors que le bytecode Python n'en contient pas. Sur A cet égard, la machine virtuelle Python (et Bash, Perl, Ruby, etc.) est vraiment plus lente que la machine virtuelle Java. fondamentalement plus lente que la machine virtuelle Java, ou plutôt, elle a tout simplement plus de travail à faire. Il est utile de considérer quelles informations sont contenues dans les différents formats de bytecode :

  • llvm : registres du processeur
  • Java : types de données primitives
  • Python : types définis par l'utilisateur

Pour faire une analogie avec le monde réel : LLVM travaille avec des atomes, la machine virtuelle Java travaille avec des molécules, et la machine virtuelle Python travaille avec des matériaux. Puisque tout doit finalement se décomposer en particules subatomiques (opérations de la machine réelle), la machine virtuelle Python a la tâche la plus complexe. opérations de la machine), la machine virtuelle Python a la tâche la plus complexe.

Les interprètes/compilateurs de langages à typage statique n'ont tout simplement pas le même bagages que les interprètes/compilateurs de langages à typage dynamique. Les programmeurs des langages à typage statique doivent prendre le relais, pour lesquels les performances en sont le prix. Cependant, tout comme toutes les fonctions non déterministes sont déterministes, tous les langages dynamiquement typés sont secrètement statiques. statiquement typés. Les différences de performances entre les deux familles de langages devraient donc se stabiliser au moment où Python changera son nom en HAL 9000.

Les machines virtuelles des langages dynamiques comme Python implémentent une machine logique idéalisée, et ne correspondent pas nécessairement à un matériel physique réel. matériel physique réel. La machine virtuelle Java, par contre, est plus similaire en termes de à un compilateur C classique, sauf qu'au lieu d'émettre des instructions de machine des instructions machine, elle exécute des routines intégrées. En Python, un nombre entier est un objet Python avec un tas d'attributs et de méthodes qui lui sont attachés. En Java, un int est un nombre désigné de bits, généralement 32. Ce n'est pas vraiment une comparaison équitable. Les entiers Python doivent être comparés à la classe Java Integer de Java. Le type de données primitif "int" de Java ne peut pas être comparé à quoi que ce soit dans le langage Python. dans le langage Python, parce que le langage Python n'a pas cette couche de primitives. primitives, tout comme le bytecode Python.

Comme les variables Java sont explicitement typées, on peut raisonnablement s'attendre à ce que quelque chose comme Jython pour être dans la même fourchette que cPython . D'autre part, une machine virtuelle Java implémentée en Python est presque garantie d'être plus lente que la boue. Et ne vous attendez pas à ce que Ruby, Perl, etc, s'en sortent mieux. Ils n'ont pas été conçus pour cela. Ils ont été conçus pour "scripting", ce que l'on appelle la programmation dans un langage dynamique.

Chaque opération qui a lieu dans une machine virtuelle doit finalement toucher du matériel réel. Les machines virtuelles contiennent des routines précompilées qui sont suffisamment générales pour exécuter toute combinaison d'opérations logiques. Une machine virtuelle n'émet peut-être pas de nouvelles instructions machine, mais elle exécute certainement ses propres routines encore et encore dans des séquences arbitrairement complexes. La machine virtuelle Java, la machine virtuelle Python et toutes les autres machines virtuelles à usage général sont identiques dans le sens où elles peuvent être amenées à exécuter n'importe quelle logique dont vous pouvez rêver, mais elles sont différentes en termes de tâches qu'elles prennent en charge et de tâches qu'elles laissent au programmeur.

Psyco for Python n'est pas une machine virtuelle Python à part entière, mais un compilateur juste-à-temps qui détourne la machine virtuelle Python normale à des endroits où elle pense que le programme est prêt à fonctionner. juste à temps qui détourne la machine virtuelle Python normale aux endroits où il pense pouvoir compiler quelques lignes de code -- principalement des boucles où il pense que le type primitif primitif d'une variable restera constant même si la valeur change à chaque itération. chaque itération. Dans ce cas, il peut renoncer à une partie de la détermination incessante du type de la machine virtuelle régulière. de la machine virtuelle ordinaire. Vous devez être un peu prudent, Cependant, vous devez être un peu prudent, de peur de retirer le type sous les pieds de Psyco. Pysco, cependant, sait généralement qu'il faut se rabattre sur la machine virtuelle régulière s'il n'est pas n'est pas complètement sûr que le type ne changera pas.

La morale de l'histoire est que l'information sur les types de données primitives est vraiment utile pour un compilateur/machine virtuelle.

Enfin, pour mettre tout cela en perspective, considérez ceci : un programme Python exécuté par un interpréteur/machine virtuelle Python implémenté en Java et s'exécutant sur un interpréteur/machine virtuelle Java machine virtuelle implémentée en LLVM fonctionnant sur une machine virtuelle qemu fonctionnant sur un iPhone. s'exécutant sur un iPhone.

permalien

4 votes

trying to write any statically-typed code interactively would be tedious . Si vous connaissez OCaml et Haskell, vous verrez que ce n'est pas vrai puisqu'ils sont très des langages concis à typage statique.

0 votes

@MatthiasBraun Je peux convenir que ces langages fonctionnels produisent un code concis mais cela ne signifie pas nécessairement qu'ils sont bien adaptés au mode interactif. Si OCaml et Haskell étaient typés dynamiquement comme lisp, ils fonctionneraient mieux en mode interactif, je suppose.

148voto

Tall Jeff Points 6065

Une machine virtuelle est un environnement informatique virtuel avec un ensemble spécifique d'instructions atomiques bien définies qui sont prises en charge indépendamment de tout langage spécifique et qui sont généralement considérées comme un bac à sable en soi. La machine virtuelle est analogue au jeu d'instructions d'un CPU spécifique et a tendance à travailler à un niveau plus fondamental avec des blocs de construction très basiques de telles instructions (ou codes d'octets) qui sont indépendants du suivant. Une instruction s'exécute de manière déterministe en se basant uniquement sur l'état actuel de la machine virtuelle et ne dépend pas d'informations situées ailleurs dans le flux d'instructions à ce moment précis.

Un interprète, quant à lui, est plus sophistiqué dans la mesure où il est conçu pour analyser un flux syntaxique d'un langage spécifique et d'une grammaire spécifique qui doit être décodé dans le contexte des éléments qui l'entourent. Vous ne pouvez pas regarder chaque octet ou même chaque ligne isolément et savoir exactement ce qu'il faut faire ensuite. Les mots du langage ne peuvent pas être pris isolément comme ils peuvent l'être par rapport aux instructions (codes d'octets) d'une machine virtuelle.

Un compilateur Java convertit le langage Java en un flux de codes d'octets, tout comme un compilateur C convertit les programmes en langage C en code d'assemblage. Un interprète, quant à lui, ne convertit pas vraiment le programme en une forme intermédiaire bien définie, il prend simplement les actions du programme dans le cadre du processus d'interprétation de la source.

Un autre test de la différence entre une VM et un interprète est de savoir si vous pensez qu'elle est indépendante de la langue. Ce que nous appelons la VM Java n'est pas vraiment spécifique à Java. Vous pourriez créer un compilateur à partir d'autres langages qui produirait des codes d'octets pouvant être exécutés sur la JVM. D'un autre côté, je ne pense pas que l'on puisse vraiment penser à "compiler" un autre langage que Python en Python pour qu'il soit interprété par l'interpréteur Python.

En raison de la sophistication du processus d'interprétation, il peut s'agir d'un processus relativement lent....specifiquement l'analyse syntaxique et l'identification des éléments du langage, etc. et la compréhension du contexte de la source pour pouvoir entreprendre le processus d'exécution dans l'interpréteur. Pour aider à accélérer de tels langages interprétés, nous pouvons définir des formes intermédiaires de code source pré-analysé et pré-tokénisé qui est plus facilement interprété directement. Ce type de forme binaire est toujours interprété au moment de l'exécution, il part simplement d'une forme beaucoup moins lisible par l'homme pour améliorer les performances. Cependant, la logique qui exécute cette forme n'est pas une machine virtuelle, car ces codes ne peuvent toujours pas être pris isolément - le contexte des tokens environnants est toujours important, mais ils sont maintenant sous une forme différente plus efficace pour l'ordinateur.

9 votes

J'avais l'impression que python générait du byte code, pyc, ou est-ce que c'est ce à quoi vous faites référence par "aider à accélérer de tels langages interprétés, c'est là que nous pouvons définir des formes intermédiaires de code source pré-parsé, pré-tokénisé qui est plus facilement interprété directement."

42 votes

@InSciTek Jeff : D'après votre réponse, il n'est pas clair si vous savez que Python utilise aussi une machine virtuelle.

4 votes

@TZ - L'implémentation populaire de Python est un compilateur Python avec une VM en arrière-plan. En mode interactif, c'est un peu un hybride avec à la fois un interpréteur frontal et un compilateur dorsal. Cependant, ce sont des choix de mise en œuvre. J'ai essayé de décrire la différence entre les concepts de VM et d'interpréteur.

74voto

Mr Fooz Points 21092

La différence de terminologie s'explique probablement par le fait que l'on pense normalement à fournir à l'interpréteur python un code source brut lisible par l'homme, sans se soucier du bytecode et de tout le reste.

En Java, vous devez explicitement compiler en bytecode, puis exécuter uniquement le bytecode, et non le code source, sur la machine virtuelle.

Même si Python utilise une machine virtuelle sous la couverture, du point de vue de l'utilisateur, on peut ignorer ce détail la plupart du temps.

4 votes

Je suis d'accord. Cette différence de terminologie se résume vraiment à l'expérience de l'utilisateur final (le développeur, donc). Elle n'a rien à voir avec de réelles différences techniques, car la frontière technique est si incroyablement floue qu'elle est pratiquement inexistante.

2 votes

+1 : Et -- plus important -- quel est le but ? Quel programme ne pouvez-vous pas écrire à cause de cette distinction ? Quelle trace de pile vous perturbe ? Quelle bibliothèque ne semble pas fonctionner correctement ?

0 votes

@S.Lott Parce qu'il est toujours bon de gagner des arguments avec ses collègues ;)

19voto

Adeel Ansari Points 24434

Interprète traduit le code source en une représentation intermédiaire efficace (code) et l'exécute immédiatement.

Machine virtuelle L'interpréteur, qui fait partie du système d'interprétation, exécute explicitement un code précompilé stocké, construit par un compilateur.

Une caractéristique très importante d'une machine virtuelle est que le logiciel qui y est exécuté est limité aux ressources fournies par la machine virtuelle. Plus précisément, il ne peut pas sortir de son monde virtuel. Pensez à l'exécution sécurisée de code à distance, aux applets Java.

Dans le cas de python, si nous gardons pyc comme mentionné dans le commentaire de ce billet, le mécanisme ressemblerait alors plus à une VM, et ce bytecode s'exécuterait plus rapidement -- il serait toujours interprété mais sous une forme beaucoup plus conviviale pour l'ordinateur. Si nous regardons tout cela dans son ensemble, PVM est la dernière étape de Python Interpreter.

En résumé, lorsque nous faisons référence à l'interpréteur Python, cela signifie que nous le considérons comme un tout, et lorsque nous disons PVM, cela signifie que nous parlons d'une partie de l'interpréteur Python, un environnement d'exécution. De la même manière que pour Java, nous faisons référence à différentes parties de manière différente : JRE, JVM, JDK, etc.

Pour en savoir plus, entrée Wikipedia : Interprète et Machine virtuelle . Encore un autre ici . Vous trouverez ici le Comparaison des machines virtuelles d'application . Il aide à comprendre la différence entre les compilateurs, les interprètes et les machines virtuelles.

12voto

Daniel Naab Points 9857

Le terme interprète est un terme ancien qui remonte aux premiers langages de script shell. Les "langages de script" ayant évolué vers des langages complets et les plates-formes correspondantes étant devenues plus sophistiquées et protégées par des bacs à sable, la distinction entre une machine virtuelle et un interpréteur (au sens de Python) est très faible, voire inexistante.

L'interpréteur Python fonctionne toujours de la même manière qu'un shell script, dans le sens où il peut être exécuté sans étape de compilation séparée. Au-delà de cela, les différences entre l'interpréteur de Python (ou de Perl ou de Ruby) et la machine virtuelle de Java sont principalement des détails de mise en œuvre. (On pourrait arguer que Java est plus complètement sandboxé que Python, mais tous deux donnent finalement accès à l'architecture sous-jacente via une interface C native).

1 votes

Il existe des shells java qui peuvent exécuter du code java sans étapes de compilation séparées (visibles par l'utilisateur).

1 votes

Donnez-moi le nom :D

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X