it-swarm.com.de

Java "Virtual Machine" vs. Python "Interpreter" -Sprache?

Es scheint selten, von einer "virtuellen Maschine" von Python zu lesen, während in Java die "virtuelle Maschine" ständig verwendet wird.

Beide interpretieren Bytecodes. Warum nennt man eine virtuelle Maschine und die andere einen Interpreter?

177
twils

Eine virtuelle Maschine ist eine virtuelle Computerumgebung mit einem bestimmten Satz gut definierter atomarer Anweisungen, die unabhängig von einer bestimmten Sprache unterstützt werden und im Allgemeinen als Sandkasten für sich betrachtet werden. Das VM ist analog zu einem Befehlssatz einer bestimmten CPU und neigt dazu, auf einer grundlegenderen Ebene mit sehr grundlegenden Bausteinen solcher Befehle (oder Bytecodes) zu arbeiten, die unabhängig von den nächsten sind. Ein Befehl wird deterministisch nur auf der Grundlage des aktuellen Zustands der virtuellen Maschine ausgeführt und hängt zu diesem Zeitpunkt nicht von Informationen an anderer Stelle im Befehlsstrom ab.

Ein Interpreter dagegen ist komplexer, da er darauf ausgelegt ist, einen Strom einer Syntax einer bestimmten Sprache und eines bestimmten Grammatikers zu parsen, der im Kontext der umgebenden Token dekodiert werden muss. Sie können nicht jedes Byte oder jede Zeile isoliert betrachten und wissen genau, was als Nächstes zu tun ist. Die Token in der Sprache können nicht isoliert wie die Anweisungen (Byte-Codes) einer VM verwendet werden.

Ein Java-Compiler konvertiert Java-Sprache in einen Bytecode-Stream, der sich von einem C-Compiler unterscheidet, und konvertiert C-Sprache-Programme in Assemblycode. Ein Interpreter hingegen konvertiert das Programm nicht wirklich in eine genau definierte Zwischenform. Es werden lediglich die Programmaktionen als eine Frage der Interpretation der Quelle betrachtet.

Ein weiterer Test für den Unterschied zwischen einem VM und einem Interpreter ist, ob Sie ihn für sprachunabhängig halten. Was wir als Java VM wissen, ist nicht wirklich Java-spezifisch. Sie können einen Compiler aus anderen Sprachen erstellen, die zu Bytecodes führen, die in der JVM ausgeführt werden können. Auf der anderen Seite denke ich nicht, dass wir wirklich daran denken würden, eine andere Sprache als Python in Python für die Interpretation durch den Python-Interpreter zu kompilieren.

Aufgrund der Komplexität des Interpretationsprozesses kann dies ein relativ langsamer Prozess sein ... insbesondere das Analysieren und Identifizieren der Sprachmarker usw. und das Verstehen des Kontextes der Quelle, um den Ausführungsprozess innerhalb des Interpreters durchführen zu können. Zur Beschleunigung solcher interpretierten Sprachen können hier Zwischenformen von vorparsedem, vor-tokenisiertem Quellcode definiert werden, der direkter interpretiert werden kann. Diese Art von binärer Form wird immer noch zur Ausführungszeit interpretiert. Sie beginnt gerade mit einer weniger lesbaren Form, um die Leistung zu verbessern. Die Logik, die dieses Formular ausführt, ist jedoch keine virtuelle Maschine, da diese Codes immer noch nicht isoliert betrachtet werden können - der Kontext der umgebenden Token ist immer noch von Bedeutung, sie befinden sich gerade in einer anderen, effizienteren Form.

120
Tall Jeff

In diesem Beitrag bezieht sich "virtuelle Maschine" auf die Verarbeitung virtueller Maschinen, nicht auf virtuelle Systemmaschinen wie Qemu oder Virtualbox. Eine virtuelle Prozessmaschine ist einfach ein Programm, das eine allgemeine Programmierumgebung bereitstellt - ein Programm, das programmiert werden kann.

Java hat einen Interpreter sowie eine virtuelle Maschine, und Python hat eine virtuelle Maschine sowie einen Interpreter. Der Grund, warum "virtuelle Maschine" in Java häufiger vorkommt und "Interpreter" in Python häufiger vorkommt, hat viel mit dem Hauptunterschied zwischen den beiden Sprachen zu tun: statisches Tippen (Java) vs. dynamisches Tippen (Python). In diesem Zusammenhang bezieht sich "Typ" auf primitive Datentypen - Typen, die die speicherinterne Größe der Daten vorschlagen. Die virtuelle Maschine Java hat es einfach. Der Programmierer muss den primitiven Datentyp jeder Variablen angeben. Dies liefert ausreichende Informationen, damit der Bytecode Java nicht nur von der virtuellen Maschine Java interpretiert und ausgeführt werden kann, sondern auch in Maschinenanweisungen kompiliert . Die virtuelle Maschine Python ist insofern komplexer, als sie die zusätzliche Aufgabe übernimmt, vor der Ausführung jeder Operation anzuhalten, um die primitiven Datentypen für jede an der Operation beteiligte Variable oder Datenstruktur zu bestimmen. Python befreit den Programmierer vom Denken in primitiven Datentypen und ermöglicht es, Operationen auf einer höheren Ebene auszudrücken. Der Preis dieser Freiheit ist Leistung. "Interpreter" ist der bevorzugte Begriff für Python, da es zum Überprüfen von Datentypen eine Pause einlegen muss und auch, weil die vergleichsweise prägnante Syntax dynamisch typisierter Sprachen für interaktive Schnittstellen gut geeignet ist. Es gibt keine technische Barriere für die Erstellung einer interaktiven Java - Schnittstelle, aber der Versuch, statisch typisierten Code interaktiv zu schreiben, wäre mühsam, sodass dies einfach nicht der Fall ist.

In der Java Welt stiehlt die virtuelle Maschine die Show, weil sie Programme ausführt, die in einer Sprache geschrieben sind, die tatsächlich in Maschinenanweisungen kompiliert werden kann, und das Ergebnis ist Geschwindigkeit und Ressourceneffizienz. Java Bytecode kann von der virtuellen Maschine Java mit einer Leistung ausgeführt werden, die der von kompilierten Programmen relativ nahe kommt. Dies ist auf das Vorhandensein von primitiven Datentypinformationen im Bytecode zurückzuführen. Die virtuelle Maschine Java ordnet Java einer eigenen Kategorie zu:

portabel interpretierte statisch typisierte Sprache

Das nächstnächste ist LLVM, aber LLVM arbeitet auf einer anderen Ebene:

portabel interpretierte Assemblersprache

Der Begriff "Bytecode" wird sowohl in Java als auch in Python verwendet, aber nicht jeder Bytecode wird gleich erstellt. Bytecode ist nur der Oberbegriff für Zwischensprachen, die von Compilern/Interpreten verwendet werden. Sogar C-Compiler wie gcc verwenden ein Zwischensprache (oder mehrere) , um die Arbeit zu erledigen. Java Bytecode enthält Informationen zu primitiven Datentypen, Python Bytecode nicht. In dieser Hinsicht ist die virtuelle Maschine Python (und Bash, Perl, Ruby usw.) im Grunde genommen langsamer als die virtuelle Maschine Java, oder vielmehr, sie hat einfach mehr Arbeit zu erledigen tun. Es ist nützlich zu prüfen, welche Informationen in verschiedenen Bytecode-Formaten enthalten sind:

  • llvm: CPU-Register
  • Java: primitive Datentypen
  • Python: benutzerdefinierte Typen

Um eine reale Analogie zu zeichnen: LLVM arbeitet mit Atomen, die virtuelle Maschine Java arbeitet mit Molekülen und die virtuelle Maschine Python arbeitet mit Materialien. Da sich irgendwann alles in subatomare Partikel zerlegen muss (reale Maschinenoperationen), hat die virtuelle Maschine Python die komplexeste Aufgabe.

Dolmetscher/Compiler für statisch typisierte Sprachen haben einfach nicht das gleiche Gepäck wie Dolmetscher/Compiler für dynamisch typisierte Sprachen. Programmierer von statisch getippten Sprachen müssen die Lücke schließen, für die sich die Leistung auszahlt. Ebenso wie alle nicht deterministischen Funktionen geheim deterministisch sind, sind auch alle dynamisch typisierten Sprachen geheim statisch typisiert. Leistungsunterschiede zwischen den beiden Sprachfamilien sollten daher ungefähr zu dem Zeitpunkt ausgeglichen werden, an dem Python seinen Namen in HAL 9000 ändert.

Die virtuellen Maschinen dynamischer Sprachen wie Python implementieren eine idealisierte logische Maschine und entsprechen nicht unbedingt einer realen physischen Hardware. Die virtuelle Maschine Java ähnelt in ihrer Funktionalität eher einem klassischen C-Compiler, abgesehen davon, dass sie keine Maschinenbefehle ausgibt, sondern integrierte Routinen ausführt. In Python ist eine Ganzzahl ein Python -Objekt mit einer Reihe von Attributen und Methoden. In Java ist ein int eine festgelegte Anzahl von Bits, normalerweise 32. Dies ist kein wirklich fairer Vergleich. Python Ganzzahlen sollten wirklich mit der Java Ganzzahlklasse verglichen werden. Javas primitiver Datentyp "int" kann mit nichts in der Sprache Python verglichen werden, da der Sprache Python einfach diese Ebene von Primitiven fehlt, und auch Python Bytecode.

Da Java -Variablen explizit typisiert sind, kann man davon ausgehen, dass sich die Leistung von Jython im selben Bereich befindet wie cPython . Andererseits ist eine in Java implementierte Python virtuelle Maschine fast garantiert langsamer als Schlamm. Und erwarten Sie nicht, dass Ruby, Perl usw. besser abschneiden. Sie waren nicht dafür ausgelegt. Sie wurden für "Scripting" entwickelt, was als Programmieren in einer dynamischen Sprache bezeichnet wird.

Jeder Vorgang, der in einer virtuellen Maschine ausgeführt wird, muss schließlich auf die reale Hardware zutreffen. Virtuelle Maschinen enthalten vorkompilierte Routinen, die allgemein genug sind, um eine beliebige Kombination von logischen Operationen auszuführen. Eine virtuelle Maschine gibt möglicherweise keine neuen Maschinenbefehle aus, führt jedoch ihre eigenen Routinen in beliebig komplexen Sequenzen immer wieder aus. Die virtuelle Maschine Java, die virtuelle Maschine Python und alle anderen universellen virtuellen Maschinen sind in dem Sinne gleich, dass sie dazu gebracht werden können, jede erdenkliche Logik auszuführen Sie unterscheiden sich jedoch darin, welche Aufgaben sie übernehmen und welche Aufgaben sie dem Programmierer überlassen.

Psyco für Python ist keine vollständige Python virtuelle Maschine, sondern ein Just-in-Time-Compiler, der die reguläre Python virtuelle Maschine an Stellen hijackt, die er für möglich hält Kompilieren Sie einige Codezeilen - hauptsächlich Schleifen, bei denen der primitive Typ einer Variablen auch dann konstant bleibt, wenn sich der Wert bei jeder Iteration ändert. In diesem Fall kann auf einen Teil der zufälligen Typbestimmung der regulären virtuellen Maschine verzichtet werden. Sie müssen jedoch ein wenig vorsichtig sein, damit Sie den Typ nicht unter Psycos Füßen herausziehen. Pysco weiß jedoch normalerweise, dass es einfach auf die normale virtuelle Maschine zurückgreift, wenn es nicht ganz sicher ist, dass sich der Typ nicht ändert.

Die Moral der Geschichte ist, dass primitive Datentypinformationen für einen Compiler/eine virtuelle Maschine wirklich hilfreich sind.

Betrachten Sie abschließend Folgendes: Ein Python Programm, das von einem Python Interpreter/einer virtuellen Maschine ausgeführt wird, die in Java implementiert ist und auf einem Java In LLVM implementierter Interpreter/virtuelle Maschine, der in einer auf einem iPhone ausgeführten virtuellen qemu-Maschine ausgeführt wird.

Permalink

149
Poor Yorick

Wahrscheinlich ist ein Grund für die unterschiedliche Terminologie, dass man normalerweise denkt, dass man den Python-Interpreter mit rohem, lesbarem Quellcode füttert und sich nicht mit Bytecode und all dem beschäftigt. 

In Java müssen Sie explizit zu Bytecode kompilieren und dann nur den Bytecode und nicht den Quellcode auf der VM ausführen. 

Obwohl Python eine virtuelle Maschine unter den Deckblättern verwendet, können diese Details aus Sicht des Benutzers meistens ignoriert werden. 

56
Mr Fooz

Interpreter übersetzt den Quellcode in eine effiziente Zwischendarstellung (Code) und führt diese sofort aus.

Virtual Machine führt explizit gespeicherten vorkompilierten Code aus, der von einem Compiler erstellt wurde, der Teil des Interpretersystems ist.

Ein sehr wichtiges Merkmal einer virtuellen Maschine ist, dass die darin ausgeführte Software auf die von der virtuellen Maschine bereitgestellten Ressourcen beschränkt ist. Genau genommen kann es nicht aus seiner virtuellen Welt herausbrechen. Denken Sie an die sichere Ausführung von Remote-Code, Java-Applets. 

Im Falle von Python würden, wenn wir pyc -Dateien behalten, wie im Kommentar dieses Beitrags erwähnt, der Mechanismus mehr wie eine VM aussehen, und dieser Bytecode wird schneller ausgeführt - er würde aber trotzdem interpretiert von einer viel computerfreundlicheren Form. Wenn wir dies als Ganzes betrachten, ist PVM ein letzter Schritt von Python Interpreter.

Unter dem Strich bedeutet Python Interpreter, dass wir es als Ganzes bezeichnen, und wenn wir PVM sagen, heißt das, dass wir nur über einen Teil von Python Interpreter sprechen, einer Laufzeitumgebung. Ähnlich wie bei Java beziehen wir uns auf verschiedene Teile von differentyl, JRE, JVM, JDK usw.

Weitere Informationen finden Sie im Wikipedia-Eintrag: Interpreter und Virtual Machine . Noch eine hier . Hier finden Sie den Vergleich von Anwendungs-Virtual Machines . Es hilft, den Unterschied zwischen Compilern, Dolmetschern und VMs zu verstehen.

14
Adeel Ansari

Der Begriff Interpreter ist ein älterer Begriff, der auf frühere Shell-Skriptsprachen zurückgeht. Als sich "Skriptsprachen" zu voll ausgestatteten Sprachen entwickelt haben und die entsprechenden Plattformen immer raffinierter und sandboxiger sind, ist der Unterschied zwischen einer virtuellen Maschine und einem Interpreter (im Sinne von Python) sehr klein oder nicht vorhanden.

Der Python-Interpreter funktioniert weiterhin wie ein Shell-Skript, dh er kann ohne separaten Kompilierungsschritt ausgeführt werden. Darüber hinaus sind die Unterschiede zwischen dem Python-Interpreter (oder Perl oder Ruby) und der virtuellen Maschine von Java hauptsächlich Implementierungsdetails. (Man könnte argumentieren, dass Java eine umfassendere Sandbox als Python ist, aber beide bieten letztendlich über eine native C-Schnittstelle Zugriff auf die zugrunde liegende Architektur.)

12
Daniel Naab

Es gibt keinen wirklichen Unterschied zwischen ihnen, die Menschen folgen einfach den Konventionen, die die Schöpfer gewählt haben.

9
Cody Brocious

Um eine ausführliche Antwort auf die Frage " Warum Java virtuelle Maschine, aber Python Interpreter? " zu geben, versuchen wir es noch einmal auf dem Gebiet der Kompilationstheorie als Ausgangspunkt der Diskussion.

Der typische Prozess der Programmkompilierung umfasst die folgenden Schritte:

  1. Lexikalische Analyse . Zerlegt Programmtext in sinnvolle "Wörter" mit dem Namen Token (im Rahmen des Vorgangs werden alle Kommentare, Leerzeichen, Zeilenumbrüche usw. entfernt, da sie das Programmverhalten nicht beeinflussen). Das Ergebnis ist ein geordneter Strom von Token.
  2. Syntaxanalyse . Bildet den sogenannten Abstract Syntax Tree (AST) aus dem Token-Stream. AST stellt Beziehungen zwischen Token her und definiert infolgedessen eine Reihenfolge der Bewertung des Programms.
  3. Semantische Analyse . Überprüft die semantische Korrektheit von AST anhand von Informationen zu Typen und einem Satz semantischer Regeln der Programmiersprache. (Zum Beispiel ist a = b + c Eine korrekte Aussage aus Sicht der Syntax, aber aus Sicht der Semantik völlig falsch, wenn a als konstantes Objekt deklariert wurde.)
  4. Zwischencodegenerierung . Serialisiert AST in den linear geordneten Strom von maschinenunabhängigen "primitiven" Operationen. Tatsächlich durchläuft der Codegenerator AST und protokolliert die Reihenfolge der Bewertungsschritte. Infolgedessen erhalten wir durch die baumartige Darstellung des Programms eine viel einfachere listenartige Darstellung, bei der die Reihenfolge der Programmauswertung beibehalten wird.
  5. Maschinencodegenerierung . Das Programm in Form eines maschinenunabhängigen "primitiven" Bytecodes wird in Maschinencode einer bestimmten Prozessorarchitektur übersetzt.

Okay. Definieren wir nun die Begriffe.

Interpreter, im klassischen Sinne dieses Wortes, geht von einer Ausführung aus, die auf der Programmbewertung basiert, die auf AST basiert, die direkt aus dem Programm erzeugt wurde Text. In diesem Fall wird ein Programm in Form von Quellcode verteilt und der Interpreter wird häufig dynamisch (Anweisung für Anweisung oder Zeile für Zeile) mit Programmtext gespeist. . Für jede Eingabeanweisung erstellt der Interpreter sein AST und wertet es sofort aus, indem er den "Status" des Programms ändert. Dies ist ein typisches Verhalten von Skriptsprachen. Betrachten Sie beispielsweise Bash, Windows CMD usw. Konzeptionell geht Python auch so vor.

Wenn wir den AST-basierten Ausführungsschritt für die Erzeugung eines maschinenunabhängigen binären Bytecode-Zwischenschritts im Interpreter ersetzen, teilen wir den gesamten Prozess der Programmausführung in zwei separate Phasen auf: Kompilierung und Ausführung. In diesem Fall wird das, was zuvor ein Interpreter war, zu einem Bytecode-Compiler, der das Programm von der Form des text in eine binary Form umwandelt. Dann wird das Programm in dieser binären Form verteilt, jedoch nicht in Form von Quellcode. Auf der Benutzermaschine wird dieser Bytecode in eine neue Entität eingegeben - virtuelle Maschine, die diesen Bytecode tatsächlich interpretiert. Aus diesem Grund werden virtuelle Maschinen auch Bytecode-Interpreter genannt. Aber lenken Sie hier Ihre Aufmerksamkeit! Ein klassischer Interpreter ist ein Textinterpreter, aber eine virtuelle Maschine ist ein Binärinterpreter! Dies ist ein Ansatz von Java und C #.

Schließlich, wenn wir die Maschinencodegenerierung zum Bytecode-Compiler hinzufügen, erhalten wir das Ergebnis, was wir einen klassischen Compiler nennen. Ein klassischer Compiler konvertiert den Programmquellcode in den Maschinencode eines bestimmten Prozessors. Dieser Maschinencode kann dann direkt ausgeführt werden auf dem Zielprozessor ohne zusätzliche Vermittlung (ohne irgendeine Art von Interpreter, weder Textinterpreter noch Binärinterpreter).

Kehren wir nun zur ursprünglichen Frage zurück und betrachten Java vs Python.

Java wurde ursprünglich so entwickelt, dass es so wenig Implementierungsabhängigkeiten wie möglich gibt. Sein Design basiert auf dem Prinzip "einmal schreiben, überall ausführen" (WORA). Zur Implementierung wurde Java ursprünglich als Programmiersprache entwickelt, die sich zu einem maschinenunabhängigen binären Bytecode kompiliert kann auf allen Plattformen ausgeführt werden, die Java unterstützen, ohne dass eine Neukompilierung erforderlich ist. Sie können über Java wie über WORA-basiertes C++ nachdenken. Tatsächlich ist Java näher an C++ als an den Skriptsprachen wie Python . Im Gegensatz zu C++ wurde Java entwickelt, um in = kompiliert zu werden binärer Bytecode der dann in der Umgebung der virtuellen Maschine ausgeführt wird, während C++ wurde entwickelt, um im Maschinencode kompiliert und dann direkt vom Zielprozessor ausgeführt zu werden.

Python wurde ursprünglich als eine Art Skriptprogrammiersprache entwickelt, die Skripte interpretiert (Programme in Form des Textes geschrieben gemäß den Programmiersprachenregeln). Aus diesem Grund hat Python zunächst eine dynamische Interpretation von einzeiligen Befehlen oder Anweisungen unterstützt, wie dies bei Bash oder Windows CMD der Fall ist. Aus dem gleichen Grund enthielten die ersten Implementierungen von Python keine Art von Bytecode-Compilern und virtuellen Maschinen zur Ausführung eines solchen Bytecodes, sondern von Anfang an Python benötigt hatte Dolmetscher der in der Lage ist, Python Programm zu verstehen und auszuwerten Text.

Aus diesem Grund neigten Java Entwickler in der Vergangenheit dazu, über Java Virtual Machine zu sprechen (weil anfangs Java wurde als Paket von Java Bytecode-Compiler und Bytecode-Interpreter geliefert - [~ # ~] jvm [~ # ~]) und Python -Entwickler tendierten dazu reden über Python Interpreter (weil anfangs Python keine virtuelle Maschine hat und war eine Art klassischer Textinterpreter, der das Programm Text direkt ausführt, ohne irgendeine Art von Kompilierung oder Umwandlung in irgendeine Form von Binärcode).

Derzeit hat Python auch die virtuelle Maschine unter der Haube und kann den Bytecode Python kompilieren und interpretieren. Und diese Tatsache macht eine zusätzliche Investition in die Verwirrung " Warum Java Virtual Machine, aber Python Interpreter? ", weil es Anscheinend enthalten Implementierungen beider Sprachen virtuelle Maschinen. Aber! Die Interpretation von Programmtexten ist auch im gegenwärtigen Moment eine Hauptmethode für die Ausführung von Python Programmen. Python -Implementierungen nutzen virtuelle Maschinen ausschließlich als Optimierungstechnik. Die Interpretation des binären Bytecodes in der virtuellen Maschine ist wesentlich effizienter als eine direkte Interpretation des ursprünglichen Programmtexts. Gleichzeitig ist das Vorhandensein der virtuellen Maschine in Python für die Python - Sprachdesigner und Python - Programmierer absolut transparent. Dieselbe Sprache kann in Dolmetschern mit und ohne virtuelle Maschine implementiert werden. Auf die gleiche Weise können dieselben Programme in Interpretern mit und ohne virtuelle Maschine ausgeführt werden, und diese Programme zeigen genau dasselbe Verhalten und erzeugen bei gleicher Eingabe dieselbe Ausgabe. Der einzige beobachtbare Unterschied ist die Geschwindigkeit der Programmausführung und der vom Interpreter belegte Speicherplatz. Daher ist die virtuelle Maschine in Python kein unvermeidbarer Bestandteil des Sprachentwurfs, sondern nur eine optionale Erweiterung des Hauptinterpreters Python.

Java kann auf ähnliche Weise betrachtet werden. Java unter der Haube verfügt über einen JIT-Compiler und kann Methoden der Klasse Java selektiv in Maschinencode der Zielplattform kompilieren und dann direkt ausführen. Aber! Java verwendet weiterhin die Bytecode-Interpretation als primäre Methode zur Java Programmausführung. Wie Python -Implementierungen, die virtuelle Maschinen ausschließlich als Optimierungstechnik nutzen, verwenden die Java -Virtuellen Maschinen Just-In-Time-Compiler ausschließlich zu Optimierungszwecken. Ebenso nur, weil die direkte Ausführung des Maschinencodes mindestens zehnmal schneller ist als die Interpretation von Java Bytecode. Und wie im Fall von Python ist das Vorhandensein des JIT-Compilers unter der Haube von JVM sowohl für Java Sprachdesigner als auch für Java Programmentwickler absolut transparent. Dieselbe Programmiersprache Java kann von JVM mit und ohne JIT-Compiler implementiert werden. Auf die gleiche Weise können dieselben Programme in JVMs mit und ohne JIT ausgeführt werden, und dieselben Programme zeigen genau dasselbe Verhalten und erzeugen auf beiden JVMs (mit und ohne JIT) dieselbe Ausgabe von denselben Eingaben. Und wie im Fall von Python wird der einzige beobachtbare Unterschied zwischen ihnen in der Ausführungsgeschwindigkeit und in der von JVM belegten Speichermenge liegen. Und schließlich ist JIT in Java, wie im Fall von Python, kein unvermeidlicher Bestandteil des Sprachentwurfs, sondern lediglich eine optionale Erweiterung der wichtigsten JVM-Implementierungen.

Vom Standpunkt des Designs und der Implementierung der virtuellen Maschinen von Java und Python unterscheiden sie sich erheblich, während beide (Achtung!) Weiterhin virtuelle Maschinen bleiben. JVM ist ein Beispiel für eine virtuelle Maschine auf niedriger Ebene mit einfachen Grundoperationen und hohen Anweisungsversandkosten. Python ist wiederum eine virtuelle Maschine auf hoher Ebene, für die Anweisungen ein komplexes Verhalten aufweisen und die Anweisungsversandkosten nicht so bedeutend sind. Java arbeitet mit einer sehr niedrigen Abstraktionsebene. JVM arbeitet mit der kleinen, genau definierten Menge primitiver Typen und weist eine sehr enge Korrespondenz (normalerweise eins zu eins) zwischen Bytecode-Befehlen und nativen Maschinencode-Befehlen auf. Im Gegensatz dazu arbeitet die virtuelle Maschine Python auf einer hohen Abstraktionsebene, sie arbeitet mit komplexen Datentypen (Objekten) und unterstützt Ad-hoc-Polymorphismus, während Bytecode-Anweisungen ein komplexes Verhalten offenbaren, das durch eine Reihe mehrerer systemeigener Maschinen dargestellt werden kann Code-Anweisungen. Beispielsweise unterstützt Python unbegrenzte Bereichsmathematik. Daher ist Python VM gezwungen, lange Arithmetiken für potenziell große Ganzzahlen zu verwenden, bei denen das Ergebnis der Operation das Computer-Word überlaufen kann. Daher kann eine Bytecode-Anweisung für Arithmetik in Python in den Funktionsaufruf in Python VM eingebunden werden, während in JVM eine arithmetische Operation in eine einfache Operation eingebunden wird, die durch eine oder wenige native Maschinenanweisungen ausgedrückt wird.

Infolgedessen können wir die nächsten Schlussfolgerungen ziehen. Virtuelle Maschine Java, aber Interpreter Python:

  1. Der Begriff der virtuellen Maschine setzt die Interpretation des binären Bytecodes voraus, während der Begriff Interpreter die Interpretation des Programmtexts übernimmt.
  2. Historisch gesehen wurde Java für die Interpretation von Binärbytecodes entworfen und implementiert, und Python wurde ursprünglich für die Interpretation von Programmtext entworfen und implementiert. Daher ist der Begriff "Java Virtual Machine" historisch und in der Java - Community gut etabliert. Ebenso ist der Begriff "Python-Interpreter" historisch und in der Python - Community gut etabliert. Die Völker neigen dazu, die Tradition zu verlängern und dieselben Begriffe zu verwenden, die lange zuvor verwendet wurden.
  3. Derzeit ist die Interpretation von Binärbytecodes für Java die wichtigste Methode zur Programmausführung, während die JIT-Kompilierung nur eine optionale und transparente Optimierung darstellt. Und für Python ist derzeit die Interpretation von Programmtexten eine primäre Methode zur Ausführung von Python - Programmen, während die Kompilierung in Python VM - Bytecode nur eine optionale und transparente Optimierung darstellt.

Daher verfügen sowohl Java als auch Python über virtuelle Maschinen, die binäre Bytecode-Interpreter sind, was zu Verwirrung führen kann, z. B. " Warum Java virtuelle Maschine, aber Python Interpreter? ". Der entscheidende Punkt hierbei ist, dass für Python eine virtuelle Maschine kein primäres oder notwendiges Mittel zur Programmausführung ist. es ist nur eine optionale Erweiterung des klassischen Textinterpreters. Andererseits ist eine virtuelle Maschine ein zentraler und unvermeidbarer Bestandteil des Java - Programmausführungs-Ökosystems. Die Auswahl der statischen oder dynamischen Typisierung für den Entwurf der Programmiersprache wirkt sich hauptsächlich nur auf die Abstraktionsebene der virtuellen Maschine aus, bestimmt jedoch nicht, ob eine virtuelle Maschine benötigt wird oder nicht. Sprachen, die beide Eingabesysteme verwenden, können so entworfen werden, dass sie in der Umgebung der virtuellen Maschine kompiliert, interpretiert oder ausgeführt werden, abhängig von ihrem gewünschten Ausführungsmodell.

6
ZarathustrA

Vergessen Sie nicht, dass in Python JIT-Compiler für x86 verfügbar sind, was das Problem weiter verwirrt. (Siehe psyco).

Eine strengere Interpretation einer "interpretierten Sprache" wird nur dann hilfreich, wenn über Performance-Probleme der VM diskutiert wird. Ruby wurde (ist?) Im Vergleich zu Python als langsamer angesehen, da es sich im Gegensatz zu Python um eine interpretierte Sprache handelt Worte, Kontext ist alles.

3
Arafangion

Nein, sie interpretieren nicht beide Bytecode.

Python interpretiert Bytecode nur, wenn Sie mit pypy laufen. Ansonsten wird es in C kompiliert und auf dieser Ebene interpretiert.

Java wird zu Bytecode kompiliert.

0

Zunächst sollten Sie verstehen, dass Programmieren oder Informatik im Allgemeinen keine Mathematik ist, und wir haben keine strengen Definitionen für die meisten Begriffe, die wir häufig verwenden.

nun zu deiner Frage:

was ist ein Dolmetscher (in der Informatik) 

Es übersetzt Quellcode nach kleinster ausführbarer Einheit und führt diese Einheit dann aus.

was ist eine virtuelle Maschine

bei JVM ist die virtuelle Maschine eine Software, die Interpreter, Klassenlader, Garbage Collector, Thread-Scheduler, JIT-Compiler und viele andere Dinge enthält.

wie Sie sehen können, ist Interpreter Teil oder JVM, und ganze JVM kann nicht als Interpreter bezeichnet werden, da sie viele andere Komponenten enthält.

Warum sollten Sie Word "Interpreter" verwenden, wenn Sie über Python sprechen

bei Java ist der Kompilierungsteil explizit. Python hingegen ist nicht explizit wie Java bezüglich seines Kompilierungs- und Interpretationsprozesses. Aus Endnutzersicht ist die Interpretation der einzige Mechanismus, der zum Ausführen von Python-Programmen verwendet wird

0
mightyWOZ