Ich kann verstehen, dass Java sowohl einen Compiler als auch einen Interpreter benötigt. Es kompiliert den Quellcode in Bytecode und eine virtuelle Maschine (unter Windows, Linux, Android usw.) übersetzt diesen Bytecode in Maschinencode für die aktuelle Architektur.
Aber warum braucht Python sowohl einen Compiler als auch einen Interpreter? Da Python nicht plattformunabhängig ist, warum nicht einfach die Interpretation verwenden? Soweit ich weiß, können Sie ein Python-Programm (zu Bytecode kompiliert) auf keinem Windows- oder Linux-Computer ohne Änderungen ausführen. Oder liege ich falsch?
Antworten:
Du bist falsch. Der Python-Bytecode ist plattformübergreifend. Siehe Ist der Python-Bytecode versionabhängig? Ist es plattformabhängig? bei Stapelüberlauf. Es ist jedoch nicht versionübergreifend kompatibel. Python 2.6 kann keine Python 2.5-Dateien ausführen. Während plattformübergreifend, ist es im Allgemeinen nicht als Verteilungsformat nützlich.
Geschwindigkeit. Die strikte Interpretation ist langsam. Praktisch jede "interpretierte" Sprache kompiliert den Quellcode tatsächlich in eine Art interne Darstellung, damit der Code nicht wiederholt analysiert werden muss. In Pythons Fall wird diese interne Darstellung auf der Festplatte gespeichert, sodass der Parsing- / Kompilierungsprozess übersprungen werden kann, wenn der Code das nächste Mal benötigt wird.
quelle
Das tut es nicht. In der Java-Sprachspezifikation gibt es nichts, was besagt, dass Java einen Compiler haben muss. Es gibt auch nichts in der Java-Sprachspezifikation, was besagt, dass Java einen Interpreter haben muss.
Ob ein Interpreter, ein Compiler oder eine Kombination aus beiden verwendet wird, liegt ganz im Ermessen des Implementierers.
Tatsächlich gibt es Implementierungen von Java, die direkt in Maschinencode kompiliert werden, z. B. den GNU Compiler für Java
gcj
. Technisch gesehen kompiliert der Oracle OpenJDK Java-Compiler auch zu Maschinencode, insbesondere JVM-Bytecode. Nun, könnte man sagen, warte eine Minute, das ist kein Maschinencode! Es gibt jedoch Software-Interpreter für x86-Maschinencode und Hardware-CPUs, die JVM-Bytecode ausführen können. Was macht also einen "nativ" und den anderen nicht?Beachten Sie, dass sich der JVM-Bytecode außerhalb der Java-Sprachspezifikation befindet, genau wie der x86-Maschinencode.
Auch dies liegt ganz beim Implementierer.
Die ursprüngliche Sun JVM wurde nie übersetzt, sondern immer interpretiert. Die aktuellen Oracle OpenJDK JVM-Interpretationen und nur die Teile, die häufig ausgeführt werden, werden kompiliert. Die Maxine Research VM wird immer JIT kompiliert. Die Implementierung von Excelsior.JET wird vorab einmal kompiliert. Die IKVM.NET-JVM wird in CIL-Bytecode kompiliert. Die Android Runtime wird einmal vor der Installation kompiliert. (Außerdem versteht die Android Runtime den JVM-Bytecode nicht, sondern verwendet Dalvik-Bytecode, eine völlig andere Sprache.)
Wieder nicht. In der Python-Sprachspezifikation gibt es nichts, was besagt, dass Python einen Compiler haben muss. Die Python-Sprachspezifikation enthält auch nichts, was besagt, dass Python einen Interpreter haben muss.
Beachten Sie, dass Python eigentlich nie interpretiert wird. Alle vorhandenen Python-Implementierungen kompilieren Python immer in eine andere Sprache. Diese Sprache kann dann wiederum interpretiert werden oder nicht, aber diese Sprache ist eine andere Sprache als Python. Python wird nicht interpretiert.
Weil Python nicht so konzipiert ist, dass es von Maschinen leicht interpretiert werden kann. Es ist so konzipiert, dass es vom Menschen leicht interpretiert werden kann. OTOH, CPython-Bytecode, ist so konzipiert, dass er von Maschinen leicht interpretiert werden kann. Es ist also sinnvoll , Code in einer für Menschen entwickelten Sprache zu schreiben und in einer für Maschinen entwickelten Sprache zu interpretieren. Um von einer zur anderen zu gelangen, müssen Sie kompilieren.
Ja, du kannst. Die CPython-VM ist sowohl für Windows als auch für Linux verfügbar, ebenso wie PyPy, Jython und IronPython.
Sprachen müssen nicht kompiliert oder interpretiert werden. Sprachen gerade sind . Tatsächlich kann eine Sprache perfekt existieren, ohne einen Interpreter oder Compiler zu haben! Zum Beispiel wurde Konrad Zuses Plankalkül, den er in den 1930er Jahren entwarf, zu seinen Lebzeiten nie umgesetzt. Sie könnten immer noch Programme darin schreiben, Sie könnten diese Programme analysieren, Gründe dafür angeben, Eigenschaften für sie beweisen ... Sie könnten sie einfach nicht ausführen. (Nun, eigentlich ist auch das falsch: Sie können sie natürlich in Ihrem Kopf oder mit Stift und Papier laufen lassen.)
Jetzt kann jede bestimmte Implementierung einer Sprache einen Compiler (oder sogar mehrere Compiler), einen Interpreter oder eine beliebige Kombination verwenden. Aber das ist ein Merkmal der Implementierung , nicht der Sprache. Jede Sprache kann mit einem Compiler implementiert werden, und jede Sprache kann mit einem Interpreter implementiert werden.
Beachten Sie jedoch, dass Sie ein Programm ohne Interpreter nicht ausführen können. Ein Compiler übersetzt einfach ein Programm von einer Sprache in eine andere. Aber das ist es. Jetzt haben Sie das gleiche Programm, nur in einer anderen Sprache. Der einzige Weg, um tatsächlich ein Ergebnis des Programms zu erhalten, besteht darin , es zu interpretieren . Manchmal ist die Sprache eine extrem einfache binäre Maschinensprache, und der Interpreter ist tatsächlich in Silikon fest codiert (und wir nennen es eine "CPU"), aber das ist immer noch Interpretation.
Diese Antwort könnte Sie auch interessieren, in der die Unterschiede und die verschiedenen Möglichkeiten zum Kombinieren von Interpreten, JIT-Compilern und AOT-Compilern sowie die Antwort auf die Unterschiede zwischen einem AOT-Compiler und einem JIT-Compiler erläutert werden .
quelle
Es ist wahr, dass der Bytecode nicht als Verteilungsformat geeignet ist, aber das bedeutet nicht, dass er nutzlos ist. Abgesehen von der Verbesserung der Startzeit auf einem bestimmten Computer ist das Interpretieren von Bytecode nach dem ersten Durchlauf auch viel einfacher als das Interpretieren eines AST oder, Gott bewahre, das zeilenweise Interpretieren.
Bytecode ist eine einfachere, regelmäßigere und kompaktere Darstellung des Codes (sowohl semantisch als auch in Bezug auf das Speicherlayout). Die Reihenfolge der Operationen ist bereits festgelegt, lokale Variablennamen wurden in eine einfachere Form (ganzzahlige Indizes) aufgelöst. Keine komplizierte Syntax, nur eine einfache Anweisung nach der anderen. Außerdem wird weniger Status benötigt: Für die zeilenweise Interpretation muss im Grunde ein ganzer Parser vorhanden sein, und ein AST-Interpreter sprengt den Aufrufstapel mit seiner Baumdurchquerung, während ein Bytecode-Interpreter nur einen kleinen Stapel für temporäre Werte benötigt und Einheimische.
Diese und andere Faktoren führen dazu, dass Bytecode-Interpreter erheblich schneller sind als andere Interpreter.
quelle