Nach CPython und Jython jetzt V8python?
Verfasst: Freitag 5. September 2008, 11:47
V8 ist die neue Open Source JavaScript-Engine von Google, entwickelt von Leuten die zuvor an der Self-VM, Strongtalk und der Hotspot-Java-VM gearbeitet hatten. Die sollten eigentlich wissen, was sie tun, auch wenn V8 (bislang) nicht an die Qualität der Optimierungen von Self und Strongtalk erreicht. In der Squeak-dev-ML befand man V8 auf VisualWorks-Smalltalk-Niveau, welches das schnellste kommerzielle Smalltalk ist, aber nicht an das Forschungsprojekt Strongtalk (übrigens auch als Open Source verfügbar) rankommt. Dafür läuft Strongtalk auch nicht 100% stabil und hat keinen Debugger. Nichts desto trotz kann sich wohl nur der auf ganz andere Art arbeitende TraceMonkey von Mozilla auf Augenhöhe mit V8 messen. Die Interpreter SpiderMonkey und SquirrelFish sowie Rhino oder auch was Microsoft so hat, haben keine Chance gegen diese neue Generation von hochoptimierenden JavaScript-Engines.
Das führt zu der Frage: Kann man die Engine nur für JavaScript oder auch für andere Sprachen wie Python nutzen? Python, kompiliert auf die JVM, ist nur etwa gleich schnell wie CPython, was ein reiner Bytecode-Interpreter ist. Da muss doch mehr möglich sein.
Da Python deutlich ähnlicher zu JavaScript wie Java ist, könnte es doch von V8 profitieren...
Ich habe bislang nur kurz in den Quelltext (alles C++, würg) geschaut und fib(32) ausprobiert. Dabei habe ich offenbar den Sweetspot von V8, nämlich Rekursion, getroffen. Das Ding ist bei diesem Benschmark schnell... verdammt schnell.
Ein kleines Subset von Python lässt sich relativ einfach effizient in JavaScript übersetzen. Das liefe dann wahrscheinlich deutlich schneller. Anderes müsste man ausprobieren.
Die prototypische Delegation von JS sollte eigentlich ermöglichen, die Vererbung von Python nachzustellen. Ich nehme an, dass die Methodensuche bei V8 stark optimiert wird (habe von monomorphic inline caches gelesen) sodass das effizient genug funktioniert. Mehrfachvererbung mit ihrer speziellen MRO kommt ja eigentlich relativ selten vor. Das einfachere Vererbungsmodell von Smalltalk und Ruby wären hier leichter abzubilden.
Pythons Grunddatentyp ist das `dict`. Das entspricht im Prinzip einem Objekt bei JS, doch dieses hat einige immer gegenwärtige Attribute. Dieses also mit einer eigenen Klasse zu simulieren wirkt unschön. Natürlich könnte es ein externer Typ sein, den man dann in C++ schreibt.
JS kennt nur einen numerischen Datentyp, Python hingegen 3 bis 4, je nachdem ob man `int` und `long` unterscheidet. Dabei halte ich `complex` für entbehrlich. Auch hier könnte man den Teil in C++ schreiben. Wahrscheinlich verbaut man sich dabei aber jetzt vorhandene Optimierungen.
Python kennt des weiteren diverse "__"-Methoden, mit denen man Standardverhalten überschreiben kann. Dies scheint mir das größte Problem bei einer möglichen Portierung zu sein. Speziell für `__getattr__` und Freunde wäre es hilfreich, eine Art `doesNotUnderstand` oder `method_missing` Funktion bereits nativ zu haben.
Pythons Funktionsargumente sind komplexer aufgebaut als die von JS, indem immer noch ein `dict` mit Schlüsselwortargumenten vorhanden sein kann und diese auf recht komplexe Weise zusammen mit Standardargumenten verknüpft werden. Hier bekommt man wahrscheinlich pro Funktionsaufruf einen mächtigen Performance-Overhead, wenn die VM das nicht speziell behandeln kann.
Aber gibt es weitere prinzipielle Probleme?
Ist das überhaupt eine interessante Idee?
Stefan
Das führt zu der Frage: Kann man die Engine nur für JavaScript oder auch für andere Sprachen wie Python nutzen? Python, kompiliert auf die JVM, ist nur etwa gleich schnell wie CPython, was ein reiner Bytecode-Interpreter ist. Da muss doch mehr möglich sein.
Da Python deutlich ähnlicher zu JavaScript wie Java ist, könnte es doch von V8 profitieren...
Ich habe bislang nur kurz in den Quelltext (alles C++, würg) geschaut und fib(32) ausprobiert. Dabei habe ich offenbar den Sweetspot von V8, nämlich Rekursion, getroffen. Das Ding ist bei diesem Benschmark schnell... verdammt schnell.
Ein kleines Subset von Python lässt sich relativ einfach effizient in JavaScript übersetzen. Das liefe dann wahrscheinlich deutlich schneller. Anderes müsste man ausprobieren.
Die prototypische Delegation von JS sollte eigentlich ermöglichen, die Vererbung von Python nachzustellen. Ich nehme an, dass die Methodensuche bei V8 stark optimiert wird (habe von monomorphic inline caches gelesen) sodass das effizient genug funktioniert. Mehrfachvererbung mit ihrer speziellen MRO kommt ja eigentlich relativ selten vor. Das einfachere Vererbungsmodell von Smalltalk und Ruby wären hier leichter abzubilden.
Pythons Grunddatentyp ist das `dict`. Das entspricht im Prinzip einem Objekt bei JS, doch dieses hat einige immer gegenwärtige Attribute. Dieses also mit einer eigenen Klasse zu simulieren wirkt unschön. Natürlich könnte es ein externer Typ sein, den man dann in C++ schreibt.
JS kennt nur einen numerischen Datentyp, Python hingegen 3 bis 4, je nachdem ob man `int` und `long` unterscheidet. Dabei halte ich `complex` für entbehrlich. Auch hier könnte man den Teil in C++ schreiben. Wahrscheinlich verbaut man sich dabei aber jetzt vorhandene Optimierungen.
Python kennt des weiteren diverse "__"-Methoden, mit denen man Standardverhalten überschreiben kann. Dies scheint mir das größte Problem bei einer möglichen Portierung zu sein. Speziell für `__getattr__` und Freunde wäre es hilfreich, eine Art `doesNotUnderstand` oder `method_missing` Funktion bereits nativ zu haben.
Pythons Funktionsargumente sind komplexer aufgebaut als die von JS, indem immer noch ein `dict` mit Schlüsselwortargumenten vorhanden sein kann und diese auf recht komplexe Weise zusammen mit Standardargumenten verknüpft werden. Hier bekommt man wahrscheinlich pro Funktionsaufruf einen mächtigen Performance-Overhead, wenn die VM das nicht speziell behandeln kann.
Aber gibt es weitere prinzipielle Probleme?
Ist das überhaupt eine interessante Idee?
Stefan