languages - python in java einbinden




Java "Virtuelle Maschine" vs. Python "Interpreter" Sprachgebrauch? (6)

Der Begriff Interpreter ist ein Legacy-Begriff, der auf frühere Shell-Skriptsprachen zurückgeht. Da sich "Skriptsprachen" zu voll funktionsfähigen Sprachen entwickelt haben und ihre entsprechenden Plattformen ausgefeilter und sandboxierter geworden sind, ist die Unterscheidung zwischen einer virtuellen Maschine und einem Interpreter (im Python-Sinne) sehr klein oder nicht existent.

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

Es scheint selten, von einer Python "virtuellen Maschine" zu lesen, während in Java "virtuelle Maschine" die ganze Zeit benutzt wird.

Beide interpretieren Byte-Codes; Warum sollte man eine virtuelle Maschine und die andere einen Dolmetscher nennen?


Eine virtuelle Maschine ist eine virtuelle Computerumgebung mit einem bestimmten Satz atomarer, gut definierter Anweisungen, die unabhängig von einer bestimmten Sprache unterstützt werden und im Allgemeinen als Sandbox für sich betrachtet werden. Die 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 der nächsten sind. Ein Befehl wird deterministisch nur auf der Grundlage des aktuellen Zustands der virtuellen Maschine ausgeführt und hängt nicht von Informationen an anderer Stelle in dem Befehlsstrom zu diesem Zeitpunkt ab.

Ein Interpreter hingegen ist insofern ausgefeilter, als er darauf zugeschnitten ist, einen Strom einer bestimmten Syntax einer bestimmten Sprache und einer bestimmten Grammer zu analysieren, die im Kontext der umgebenden Token decodiert werden müssen. Sie können nicht jedes Byte oder jede Zeile einzeln betrachten und wissen genau, was als nächstes zu tun ist. Die Tokens in der Sprache können nicht isoliert verwendet werden, wie sie in Bezug auf die Anweisungen (Byte-Codes) einer VM möglich sind.

Ein Java-Compiler konvertiert die Java-Sprache in einen Byte-Code-Stream, der nicht anders ist als ein C-Compiler, der C-Sprache-Programme in Assembler-Code umwandelt. Ein Interpreter hingegen konvertiert das Programm nicht wirklich in eine gut definierte Zwischenform, sondern nimmt lediglich die Programmaktionen als eine Frage der Interpretation der Quelle.

Ein weiterer Test des Unterschieds zwischen einer VM und einem Interpreter besteht darin, ob Sie sie als sprachunabhängig betrachten. Was wir als Java-VM kennen, ist nicht wirklich Java-spezifisch. Sie können einen Compiler aus anderen Sprachen erstellen, die zu Bytecodes führen, die auf der JVM ausgeführt werden können. Andererseits 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 Verfeinerung des Interpretationsprozesses kann dies ein relativ langsamer Prozess sein .... insbesondere das Parsen und Identifizieren der Sprachtoken usw. und das Verstehen des Kontexts der Quelle, um den Ausführungsprozess innerhalb des Interpretierers durchführen zu können. Um solche interpretierten Sprachen zu beschleunigen, können hier Zwischenformen von vorparsiertem, vor-tokenisiertem Quellcode definiert werden, der leichter direkt interpretiert werden kann. Diese Art von binärer Form wird immer noch zur Ausführungszeit interpretiert, sie beginnt nur mit einer viel weniger von Menschen 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 Tokens spielt immer noch eine Rolle, sie sind gerade jetzt in einer anderen, computereffizienteren Form.


In diesem Beitrag bezieht sich "virtuelle Maschine" auf die Verarbeitung virtueller Maschinen und nicht auf virtuelle Maschinen wie Qemu oder Virtualbox. Eine prozessvirtuelle Maschine 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 "virtuelle Maschine" ist ein häufigerer Begriff in Java und "Interpreter" ist ein häufigerer Begriff in Python hat viel mit dem großen Unterschied zwischen den beiden Sprachen zu tun: statische Typisierung (Java) vs dynamische Typisierung (Python). In diesem Zusammenhang bezieht sich "Typ" auf primitive Datentypen - Typen, die die speicherinterne Speichergröße der Daten vorschlagen. Die Java Virtual Machine hat es einfach. Es erfordert, dass der Programmierer den primitiven Datentyp jeder Variablen angibt. Dies stellt ausreichende Informationen für Java-Bytecode bereit, die nicht nur von der Java Virtual Machine interpretiert und ausgeführt werden, sondern sogar in Maschinenbefehle kompiliert werden müssen . Die virtuelle Python-Maschine ist in dem Sinne komplexer, dass sie die zusätzliche Aufgabe des Pausierens vor der Ausführung jeder Operation übernimmt, um die primitiven Datentypen für jede an der Operation beteiligte Variable oder Datenstruktur zu bestimmen. Python befreit den Programmierer davon, an primitive Datentypen zu denken, 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, weil er angehalten werden muss, um Datentypen zu untersuchen, und auch weil die vergleichsweise präzise Syntax dynamisch typisierter Sprachen für interaktive Schnittstellen gut geeignet ist. Es gibt keine technische Barriere für den Aufbau einer interaktiven Java-Schnittstelle, aber der interaktive Versuch, jeden statisch getippten Code zu schreiben, wäre mühsam, und so ist es nicht so.

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 Java-Maschine mit einer Leistung ausgeführt werden, die relativ zu der von kompilierten Programmen ist. Dies liegt an dem Vorhandensein primitiver Datentypinformationen in dem Bytecode. Die Java Virtual Machine fügt Java in eine eigene Kategorie ein:

portable interpretierte statisch typisierte Sprache

Die nächstliegende Sache ist LLVM, aber LLVM operiert auf einer anderen Ebene:

portable interpretierte Assemblersprache

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

  • llvm: cpu registriert
  • Java: primitive Datentypen
  • Python: benutzerdefinierte Typen

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

Interpreter / Compiler von statisch getippten Sprachen haben einfach nicht das gleiche Gepäck, das Interpreter / Compiler von dynamisch typisierten Sprachen haben. Programmierer von statisch getippten Sprachen müssen die Lücke füllen, für die sich die Leistung auszahlt. Genauso wie alle nichtdeterministischen Funktionen heimlich deterministisch sind, so sind auch alle dynamisch typisierten Sprachen geheim statisch typisiert. Leistungsunterschiede zwischen den beiden Sprachfamilien sollten daher zu der Zeit ausgeglichen werden, wenn Python seinen Namen in HAL 9000 ändert.

Die virtuellen Maschinen dynamischer Sprachen wie Python implementieren einige idealisierte logische Maschinen und entsprechen nicht unbedingt einer realen physischen Hardware. Im Gegensatz dazu ist die Java Virtual Machine in ihrer Funktionalität einem klassischen C-Compiler ähnlicher, außer dass sie anstelle von Maschinenanweisungen eingebaute Routinen ausführt. In Python ist eine Ganzzahl ein Python-Objekt mit einer Reihe von Attributen und Methoden. In Java ist ein int eine bestimmte Anzahl von Bits, normalerweise 32. Es ist nicht wirklich ein fairer Vergleich. Python-Ganzzahlen sollten wirklich mit der Java Integer-Klasse verglichen werden. Der primitive Java-Datentyp "int" kann nicht mit irgendetwas in der Python-Sprache verglichen werden, da der Python-Sprache einfach diese Ebene von Primitiven fehlt, ebenso wie der Python-Bytecode.

Da Java-Variablen explizit eingegeben werden, kann man vernünftigerweise erwarten, dass sich etwas wie die Jython Performance im gleichen cPython wie cPython . Auf der anderen Seite ist eine Java Virtual Machine, die in Python implementiert ist, fast garantiert langsamer als Schlamm. Und erwarte nicht, dass Ruby, Perl usw. besser abschneiden. Sie waren nicht dafür ausgelegt. Sie wurden für das "Scripting" entwickelt, das Programmieren in einer dynamischen Sprache.

Jede Operation, die in einer virtuellen Maschine stattfindet, muss schließlich echte Hardware treffen. Virtuelle Maschinen enthalten vorkompilierte Routinen, die allgemein genug sind, um eine beliebige Kombination logischer Operationen auszuführen. Eine virtuelle Maschine gibt möglicherweise keine neuen Maschinenbefehle aus, aber sie führt ihre eigenen Routinen in immer wieder komplexen Abläufen immer wieder aus. Die virtuelle Java-Maschine, die virtuelle Python-Maschine und all die anderen virtuellen Maschinen für allgemeine Zwecke sind in dem Sinne gleichwertig, dass sie dazu gebracht werden können, jede Logik auszuführen, die Sie sich ausdenken können, aber sie unterscheiden sich hinsichtlich ihrer Aufgaben übernehmen und welche Aufgaben sie dem Programmierer überlassen.

Psyco für Python ist keine vollständige virtuelle Python-Maschine, sondern ein Just-in-Time-Compiler, der die reguläre virtuelle Python-Maschine an Punkten hackt, von denen er denkt, dass sie einige Codezeilen kompilieren kann - hauptsächlich Schleifen Die Variable bleibt konstant, auch wenn sich der Wert mit jeder Iteration ändert. In diesem Fall kann auf einige Inkonsistenztyp-Ermittlungen der regulären virtuellen Maschine verzichtet werden. Du musst ein wenig vorsichtig sein, damit du den Typ nicht unter Psycos Füßen hervorziehst. Pysco weiß jedoch normalerweise, dass es nur auf die normale virtuelle Maschine zurückgreift, wenn es nicht völlig 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.

Um dies alles in die richtige Perspektive zu rücken, sollten Sie folgendes beachten: Ein Python-Programm, ausgeführt von einem in Java implementierten Python-Interpreter / virtuellen Maschine, ausgeführt auf einem Java-Interpreter / einer virtuellen Maschine, implementiert in LLVM, ausgeführt in einer qemu virtuellen Maschine, ausgeführt auf einem iPhone.

permalink


Nein, sie interpretieren nicht beide Byte-Code.

Python interpretiert nur Bytecode, wenn Sie mit Pypy arbeiten. Andernfalls wird es in C kompiliert und auf dieser Ebene interpretiert.

Java kompiliert zu Bytecode.


Wahrscheinlich ist ein Grund für die unterschiedliche Terminologie, dass man normalerweise daran denkt, den Python-Interpreter mit rohen, menschlich lesbaren Quellcode zu füllen und sich nicht um Bytecode und all das zu kümmern.

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 Abdeckungen verwendet, kann man dieses Detail aus der Sicht eines Benutzers meistens ignorieren.


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

jetzt zu deiner Frage:

was ist ein Dolmetscher (in Informatik)

Es übersetzt den Quellcode nach der kleinsten ausführbaren Einheit und führt diese Einheit dann aus.

Was ist eine virtuelle Maschine?

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

Wie Sie sehen können, ist der Interpreter ein Teil oder eine JVM und die gesamte JVM kann nicht als Interpreter bezeichnet werden, da sie viele andere Komponenten enthält.

Warum verwenden Sie das Wort "Interpreter", wenn Sie über Python sprechen

Mit Java ist der Kompilierungsteil explizit. Python hingegen ist nicht explizit als Java über seinen Kompilierungs- und Interpretationsprozess bekannt, da aus Sicht des Endbenutzers nur Python-Programme ausgeführt werden





jvm