WebKit: SquirrelFish Extreme
ml, den 19. September 2008Wir informierten Euch schon über die neue Javascript-Engine von Webkit, SquirrelFish. Bereits damals kündigten die Entwickler an, dass die neue Implementierung noch viel Platz für zukünftige Optimierungen bieten würde. Jetzt, drei Monate später, ist es soweit. Das WebKit-Team präsentiert SquirrelFish Extreme (SFX).
Durch bessere Verfahren, u. a. Generierung von nativem Code, konnte die Javascript-Geschwindigkeit nochmals deutlich gesteigert werden. Die folgende Abbildung zeigt die Performance des WebKits im SunSpider-Benchmark. Längere Balken bedeuten eine bessere Performance.
In einem Blog-Post stellen die Entwickler vier grundlegende Techniken vor, mit denen SquirrelFish Extreme arbeitet, um die Javascript-Performance zu verbessern.
Bytecode-Optimierungen
Bevor Javascript-Code ausgeführt werden kann, wird er in sogenannten Bytecode übersetzt. Bytecode hat den Vorteil, dass er plattformunabhängig ist und sich dynamisch oder statisch in nativen Code umwandeln lässt.
SFX macht sich jetzt den Polymorphismus von Funktionen (unterschiedliches Verhalten mit vielen unterschiedlichen Fällen) zu Nutze, in dem bei der Bytecode-Generierung zunächst die Standardfälle betrachtet werden. Zudem wurden die Opcodes des Bytecodes optimiert und darauf aufbauend wurden weitere Optimierungen realisiert.
Polymorpher Inline-Cache
Hinter diesem Wortungetüm verbirgt sich eine relativ einfache Technik. Obwohl Javascript eine hoch dynamische Sprache ist, sind die Objekte in Programmen doch häufig stark strukturiert. Dieses Wissen macht man sich zu Nutze und nutzt den Fall, dass viele Objekte die selbe zugrunde liegende Struktur haben.
Die selbe zugrunde liegende Struktur bedeutet, dass die Properties eines Objekt in der gleichen Reihenfolge zu finden sind. Beim ersten Zugriff auf eine solche Property wird der entsprechende Offset mit einer sogenannten Structure-ID im Cache gespeichert. Bei Zugriffen in Objekten mit der gleichen Structure-ID kann der Offset dann direkt mit wenigen Maschinen-Instruktionen aus dem Cache ermittelt werden.
Context-Threaded JIT
Ein JIT ist ein Just-In-Time-Compiler. Er erzeugt nativen Maschinencode direkt zur Laufzeit des Programms. Context-Threaded-JIT ist eine sehr einfache Form der Codegenerierung, bei der immer nur ein Opcode übersetzt wird. Komplexe Opcodes werden in Funktionsaufrufe in die Javascript-Umgebung umgewandelt. Die übersetzten Opcodes werden direkt in den Instruktionsstrom eingebettet. Damit wird zum einen der Overhead der durch das Dispatchen von Code entsteht vermieden und zum anderen können Sprünge in den Opcodes durch die Sprungvorhersage der CPU besser erkannt werden.
Der jetzt ins WebKit integrierte JIT ist nur knapp 4000 Code-Zeilen groß und erzeugt momentan nur für die IA32-Architektur nativen Code. Andere Architekturen müssen noch auf den Interpreter zurückgreifen. Allerdings sollen weitere Architekturen bald unterstützt werden. Zudem sehen die Entwickler beim JIT noch weiteres Verbesserungspotential u. a. durch bessere Registerallokation und Typ-Spezialisierung.
JIT für reguläre Ausdrücke
Viele Aufgaben im Web erfordern eine leistungsfähige Infrastruktur zum Verarbeiten von regulären Ausdrücken. Zum Beispiel beim Parsen und Validieren von JSON-Ausdrücken wird diese Funktionalität benötigt. Um hier die Geschwindigkeit zu steigern, hat das WebKit-Team die gleiche JIT-Infrastruktur wie bei der Verarbeitung des Bytecodes verwendet.
Fazit
Die Weiterentwicklung von SquirrelFish zu SquirrelFish Extreme zeigt, welches Potential noch in der Javascript-Verarbeitung steckt. Beim weithin anerkannten SunSpider-Benchmark verbessert SFX die Javascript-Performance gegenüber SquirrelFish nochmal um knapp 100 Prozent. Dabei werden auch die Techniken zur Optimierung immer ausgefeilter und die Entwickler bedienen sich dabei aktuellster Forschungsergebnisse.
Leider vergleicht Apple die Performance von SFX nicht mit der ebenfalls vor kurzem von Google in WebKit integrierten V8-Engine. V8 beeindruckte ebenfalls durch seine hohe Geschwindigkeit. Hier ist es spannend zu sehen, welche der beiden Engines momentan die Performance-Krone auf hat.