Unterschied Interpreter - virtuelle Maschine



  • das sind eigentlich unterschiedliche dinge die nicht vergleichbar sind.
    ein interpreter ist nur dafuer da code auszufuehren, fuer z.B. Java gab es eine lange zeit keinen JIT, alles lief interpretiert. eine VM hat darueber hinaus alles was eine 'machine' braucht um komplett autonom mit den resourcen zu leben die ihr zur verfuegung gestellt wurden.

    wenn du eine analogie willst, waere ein interpreter ein motor, eine VM ein fahrzeug.

    Wenn du zwei VMs startest, sollten das (wenn man bugs/exploits ausschliesst) zwei komplett getrennte welten sein. startest du zwei interpreter kann es sein dass das nichtmal moeglich ist, weil die idee ist dass du eher ein "context" innerhalb des interpreters startest. in dem laufen dann eigentlich zwei unabhaengige welten die intern aber viel teilen (z.B. speicherverwaltung). ein interpreter verlaesst sich darunter auf die vom system zur verfuegung gestellten mittel, z.b. wird speicher allokiert und freigegeben wie es passt. file handling wird vom system verwendet, manchmal hast du auch die endianess vom system darunter (java VM hat z.B. immer big endian).



  • Wobei jeder gute Interpreter sowieso mit einer VM gleichzusetzen ist. Python oder PHP machen es ja genau gleich: der Code wird kompiliert in einen Bytecode und dieser Bytecode wird dann ausgeführt. Das ist technisch nicht wirklich etwas anderes als eine VM.
    Wobei natürlich die Java VM weit mehr entwickelt ist.



  • Definiere mal "guten Interpreter" im Gegensatz zum allgemeinen Interpreter, nach dem hier gefragt wurde.



  • Python hat auch eine VM. Nur tritt sie da nicht in den Vordergrund.

    Von aussen gesehen wird in Python der Programmcode interpretiert (da reiner Text). Dröselt man den Prozess auf, wird Python erst geparsed, zu Bytecode compiliert dann schliessliche der Bytecode in der VM ausgeführt. Die hinteren Schritte sind aber versteckt.

    In Java ist die VM hingegen im Vordergrund. Das macht es möglich, Java mit anderen Sprachen zu mischen. Ginge in Python theoretisch auch, ist aber nicht vorgesehen.

    Die VM ist genau genommen auch nur ein Interpreter (Bytecode-Interpreter), aber halt mit gewissen Hardware-Abstraktions-Garantien.

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).



  • DerAndroide schrieb:

    Definiere mal "guten Interpreter" im Gegensatz zum allgemeinen Interpreter, nach dem hier gefragt wurde.

    Ein "dummer" Interpreter wäre zB die bash. Zeile für Zeile das Script auswerten und ausführen.

    Ein guter Interpreter wäre zB PHP. Zuerst wird alles in einen Bytecode kompiliert und optimiert und dann wird der Bytecode in einer VM ausgeführt.

    Natürlich ist Java hier zB ein paar Dimensionen technisch komplizierter und weiterentwicklet - aber "dumme" Interpreter wie zB bash gibt es heutzutage eher nicht. PHP, Python, JavaScript, Lua,... sie alle haben eine VM intern.



  • wimmer schrieb:

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).

    Nein, das habe ich nicht impliziert.
    Weiss nicht wie du darauf kommst.
    Lies meinen Beitrag nochmal.



  • Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.
    Wieso sollte ich dann sagen dass Python oder PHP mit Hilfe einer VM ausgeführt wird? Nur weil irgend eine Form von Zwischencode und evtl. sogar ein JIT Compiler verwendet werden?

    Oder ist per Definition alles was irgendwelchen Code "umsetzt", aber kein klassischer AST-Walker mehr ist, gleich automatisch eine VM? Wäre eine für mich komische Definition des Begriffs...



  • hustbaer schrieb:

    wimmer schrieb:

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).

    Nein, das habe ich nicht impliziert.
    Weiss nicht wie du darauf kommst.
    Lies meinen Beitrag nochmal.

    Also ich habe das gemeint:

    hustbaer schrieb:

    Oder ob ein Programm erstmal nur geparsed wird, wobei ein AST rauskommt, den man quasi 1:1 wieder zurück in Sourcecode übersetzen könnte.

    Auf Python (zumindest auf frühe Python Versionen) triffst das zweite zu, deswegen spricht man da eher von einer interpretierten Sprache.

    Der Python Bytecode ist ziemlich High-Level, da durch das Duck-Typing keine Typinformationen bekannt sein können. Vom Python AST zum Python Bytecode ist sprachbedingt ziemlich einfach (Optimierungen, wie z.B. inlinen oder Operationen umtauschen ist gar nicht erlaubt)

    Deshalb habe ich daraus geschlossen, dass Python (und Duck Typing) nach deiner Auffassung prinzipiell keine VM zulässt.

    hustbaer schrieb:

    Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.

    Das Ding heisst Python Virtual Machine, obs dir passt oder nicht. Nur dass die VM nicht von der Sprache diktiert wird, sondern von einer Implementierung festgelegt wird.



  • wimmer schrieb:

    hustbaer schrieb:

    Oder ob ein Programm erstmal nur geparsed wird, wobei ein AST rauskommt, den man quasi 1:1 wieder zurück in Sourcecode übersetzen könnte.

    Auf Python (zumindest auf frühe Python Versionen) triffst das zweite zu, deswegen spricht man da eher von einer interpretierten Sprache.

    Der Python Bytecode ist ziemlich High-Level, da durch das Duck-Typing keine Typinformationen bekannt sein können. Vom Python AST zum Python Bytecode ist sprachbedingt ziemlich einfach (Optimierungen, wie z.B. inlinen oder Operationen umtauschen ist gar nicht erlaubt)

    Deshalb habe ich daraus geschlossen, dass Python (und Duck Typing) nach deiner Auffassung prinzipiell keine VM zulässt.

    Ich meinte es ist ein Unterschied ob eine Sprache standardisiert ist, und dieser Standard eine VM beschreibt. Wie eben z.B. bei Java. Dadurch ist die Java-VM etwas explizites, greifbares. Man kann sogar andere Sprachen bauen die in der JVM laufen.

    Bei Python ist das nicht so. Für die ersten Python Versionen gab es nichtmal irgend einen echten Standard, Python war einfach "implementation defined". Mit ein bisschen informeller Beschreibung was man inetwa zu erwarten hat (<- ja, leicht untertrieben, aber prinzipiell ist/war es so).
    Wie das aktuell aussieht weiss ich nicht, vielleicht wurde da bereits nachgebessert.

    Und damit verliert der Begriff VM für mich hier etwas an Realität. Ist doch im Endeffekt einfach nur eine Sammlung von Strukturen und Techniken die die aktuelle Implementierung des Interpreters verwendet um Python auszuführen. Der könnte es aber auch genau so gut anders machen.

    hustbaer schrieb:

    Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.

    Das Ding heisst Python Virtual Machine, obs dir passt oder nicht. Nur dass die VM nicht von der Sprache diktiert wird, sondern von einer Implementierung festgelegt wird.

    Ich muss mit der Verwendung des Begriffs VM deswegen aber noch lange nicht einverstanden sein, ob es dir nun passt oder nicht 😉
    Nicht alles was irgendwo als Name/Bezeichnung/Beschreibung für etwas verwendet wird ist korrekt, nur weil der Urheber der benannten/beschriebenen Sache den Namen/die Beschreibung selbst gewählt hat.
    Wenn die Python-Katamaran dazu sagen würden wäre es deswegen immer noch kein solcher.

    Bzw. vielleicht wird anhand eines Beispiel besser klar was ich meine: Ich kann auch hergehen und eine Beschreibung für einen "bytecode" basteln der als einzige Opcodes "\r" und "\n" kennt, und damit dann eine Beschreibung für eine "VM" basteln, die 1:1 DOS Batch-Files ausführt.
    Und dann behaupten dass cmd.exe eine VM verwendet.

    Nur dass der "Befehlssatz" dieser "VM" so weit von einem realen oder gedachten Computersystem entfernt wäre, dass der Begriff mMn. nicht mehr viel Sinn macht.

    Also erlaube ich mir "VM" nur für Dinge zu verwenden, deren Befehlssatz inetwa dem entspricht was man von normalen CPUs gewohnt ist. Auf Java oder C# trifft das zu. Auf Python nicht.

    Also: welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?



  • danke für die Antworten.

    Ich fasse also den Grundtenor hier zusammen:
    1. VM nur, wenn eine vernünftige Definition (Standardisierung) dieser existiert und der Befehlssatz halbwegs dem entspricht, was man von echten Befehlssätzen (z.B. x86) her kennt
    2. ob nun AST oder Bytecode ausgeführt wird, spielt keine Rolle für die Bezeichnung als VM
    3. praktisch alle "modernen" Skriptsprachen führen nicht direkt den AST aus, sondern erzeugen Bytecode, welcher dann interpretiert wird. Ob es nun ein Bytecodeinterpreter oder eine VM ist siehe 1.

    Grund der Frage: Hatte letztens eine Diskussion mit einem Kollegen. Er meinte, bei Python handle es sich nicht um einen Interpreter, sondern um eine VM so wie bei Java.
    Ich kann nun also dagegenhalten: ja, Python erzeugt zwar Bytecode, aber als VM kann man das noch nicht bezeichnen da nicht standardisiert und zu wenig Ähnlichkeit mit "echtem" Befehlssatz.



  • Das deckt sich inetwa mit meiner Meinung zu dem Thema.
    Wie du siehst haben andere hier allerdings eine ganz andere Meinung 🙂

    Mit 1-2 leichten Modifikationen hast du aber ein Statement das nicht so leicht "angreifbar" ist, bzw. nicht mehr so stark davon abhängig was man nun als VM durchgehen lässt und was nicht:

    "Ja, Python erzeugt zwar Bytecode, aber als VM wie bei Java kann man das nicht bezeichnen, da bei Python kaum Ähnlichkeit zum Befehlssatz einer realen oder theoretischen CPU besteht, bei Java aber sehr wohl."

    Denn der Teil ist schonmal ziemlich klar, dass - selbst wenn man das was der Python Interpreter verwendet als VM bezeichnen möchte - grosse Unterschiede zwischen der JVM und der "Python VM" bestehen.

    ps: Nö, deckt sich doch nicht ganz mit meiner Meinung zu dem Thema. Etwas was auf einem AST rumrödelt würde ich grundsätzlich nicht als VM bezeichnen, da hier ebenfalls kein Code im Spiel ist der in irgendeiner Form dem einer realen oder gedachten CPU ähnlich wäre. Also doch nicht ganz unabhängig davon.



  • hustbaer schrieb:

    Wieso sollte ich dann sagen dass Python oder PHP mit Hilfe einer VM ausgeführt wird? Nur weil irgend eine Form von Zwischencode und evtl. sogar ein JIT Compiler verwendet werden?

    Also ist PHP auf hiphop(hhvm) eine VM und PHP auf dem php.net Interpreter keine VM - obwohl beide technisch einander sehr aehnlich sind. hhvm ist aber technisch etwas weiter entwickelt und formal definiert, waehrend ja PHP ansich keinen definierten standard hat.

    Willst du technische Gegebenheiten wirklich an der Existenz der Dokumentation festlegen? Die PHP VM ist gut genug definiert dass man optimizer dafuer schreiben kann die dann als extension laufen.



  • @Shade Of Mine
    OK, ich verstehe deinen Standpunkt.
    Aber beantworte du mir bitte die Fragen

    welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?

    ps: Vielleicht ist der interessantere Punkt wirklich ob der Befehlssatz und allgemeine Aufbau dem eines realen Computers ähnlich ist. Also einfache Opcodes mit einfachen Operanden, keine super-komplexen Operationen wie Lookups in String-Dictionaries um die aufzurufende Funktion zu finden.
    Nur, wenn etwas in einem offiziellen Standard beschrieben und als VM bezeichnet wird, trotz dem es dieses Kriterium nicht erfüllt, dann muss man wohl oder übel damit leben dass es von allen so bezeichnet wird.

    Wenn aber beides nicht gegeben ist, dann nehme ich mir die Freiheit Bullshit zu rufen.



  • hustbaer schrieb:

    Das deckt sich inetwa mit meiner Meinung zu dem Thema.
    Wie du siehst haben andere hier allerdings eine ganz andere Meinung 🙂

    Mit 1-2 leichten Modifikationen hast du aber ein Statement das nicht so leicht "angreifbar" ist, bzw. nicht mehr so stark davon abhängig was man nun als VM durchgehen lässt und was nicht:

    "Ja, Python erzeugt zwar Bytecode, aber als VM wie bei Java kann man das nicht bezeichnen, da bei Python kaum Ähnlichkeit zum Befehlssatz einer realen oder theoretischen CPU besteht, bei Java aber sehr wohl."

    Denn der Teil ist schonmal ziemlich klar, dass - selbst wenn man das was der Python Interpreter verwendet als VM bezeichnen möchte - grosse Unterschiede zwischen der JVM und der "Python VM" bestehen.

    Ist es denn technisch unmöglich einen Rechner zu bauen, der Python Bytecode direkt ausführt? Denke nicht, nur ziemlich aufwendig. 😉



  • @Ethon
    Nein, natürlich ist es nicht unmöglich.
    Es ist aber technisch auch nicht unmöglich einen Rechner zu bauen der direkt Batch-Files ausführt.
    Oder diverse BASIC-Dialekte.

    Nennen wir deswegen jetzt alles was BASIC oder Batch-Files ausführt VM?



  • hustbaer schrieb:

    ps: Vielleicht ist der interessantere Punkt wirklich ob der Befehlssatz und allgemeine Aufbau dem eines realen Computers ähnlich ist. Also einfache Opcodes mit einfachen Operanden, keine super-komplexen Operationen wie Lookups in String-Dictionaries um die aufzurufende Funktion zu finden.

    Ich finde auch, dass der Befehlssatz aus "einfachen" Operationen bestehen soll. Also mit Instruktionpointer und Jump, kein AST-Walker.

    Aber was sich dahinter verbirgt kann durchaus komplexer sein. Bei Java ist der GC Teil der VM und das ist durchaus nichts triviales. Ein bisschen String-Lookup ist da mMn voll ok.

    hustbaer schrieb:

    welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?

    Meine Definition:
    Bytecodeinterpreter: Code besteht nur aus einfachen Instruktionen, der Programmfluss ist vorhersehbar. Kümmert sich nur um die Ausführung, nicht um Memory-Management, oder die Datentypen.
    VM: Besteht aus Bytecodeinterpreter plus Maschinenabstraktion, d.h. Definition des Int-Datentyps, Speicherverwaltung (GC) etc. Alles ist unabhängig von der darunterliegenden Architektur, auch der Bytecodeinterpreter.

    VM nur, wenn eine vernünftige Definition (Standardisierung) dieser existiert

    Wenn es eine VM ohne Definition gibt und dann kommt eine Doku hinzu, ist die VM erst dann eine VM? Standardisiert oder nicht macht mMn gar keinen Unterschied. Eine Programmiersprache braucht auch keine formale Definition (siehe z.B. D).



  • Also die Speicherverwaltung ist mMn. nicht notwendigerweise ein Teil einer VM. Ich kenne z.B. auch keine reale Maschine die eine solche eingebaut hat.
    Und die Datentypen muss der Bytecode-Interpreter schon festlegen. Bzw. sind sie Teil der Definition des Bytecodes.

    Was bleibt jetzt also noch übrig was zum Bytecode-Interpreter dazukommen muss, damit wir es VM nennen können?



  • hustbaer schrieb:

    @Shade Of Mine
    OK, ich verstehe deinen Standpunkt.
    Aber beantworte du mir bitte die Fragen

    welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?

    Ich finde solche Trennungen einfach falsch. Du wirst nie eine perfekte Definition dafuer finden. Denn ein weiter entwickelter Interpreter ist immer eine unterentwickelte VM.

    Desto weiter er sich entwickelt desto VM aehlicher wird er und desto simpler eine VM ist, desto interpreteraehnlich ist sie.



  • Basic auf dem C64, Amiga usw ist ein reiner Interpreter. Die Technik hinter VMWare, QEmu sind VMs. Bei Java würde ich gar nicht von einer VM reden, eher einfach nur von einer Runtime Umgebung, diese ist bei Oracle Java dynamisch oder auch bei Androids ART statisch.

    Ist aber wirklich schwer zu definieren, Wikipedia sagt auf der einen Seite auch dass eine VM nur einen Abbildung eine kompletten Rechners in Software ist. Auf der anderen Seite wird bei Javas Unterbau zwar nicht direkt VM genannt, sondern JVM, aber das passt alles vorn und hinten nicht.

    VM und Laufzeitumgebung ist noch schwieriger zu trennen, aber eher vergleichbar als ein Interpreter der zusammen mit einer VM/Laufzeitumgebung arbeitet.

    Der Interpreter ist für mich die Schicht über der Laufzeitumgebung. So komme ich am besten damit klar.



  • @Shade Of Mine
    Und ich würde dann halt sagen: ein weiter entwickelter Interpreter verwendet vielleicht eine VM, aber warum sollte man sagen er ist eine VM? Speziell wenn es nur ein Implementierungsdetail ist dass etwas VM-artiges verwendet wird. Also Bytecode-Interpreter bzw. JIT-compiler.

    Gerade weil der Begriff so schwammig bzw. schlecht abgrenzbar ist. Er ist auf jeden Fall mal ein Interpreter, ganz wurst ob gebytecoded und gejitet wird, deswegen würde ich eher den Begriff verwenden und VM halt wirklich nur sagen wenn ich unterstreichen will dass hier irgendwas besonders "VM-ig" gemacht wird.


Anmelden zum Antworten