Google Tabellen ist eines der ersten Produkte von Google, das WasmGC in Chrome verwendet. Die Umstellung wurde 2022 angekündigt. Die Teams von Google Tabellen und Chrome arbeiteten gemeinsam an Standardisierung, Entwicklung und Tools, um in Echtzeit Feedback zu Optimierungen zu erhalten. Diese Partnerschaft hat einen Präzedenzfall dafür geschaffen, wie Entwicklungsteams bei Google effektiv mit Chrome zusammenarbeiten können, damit mehr Google-Apps auf WasmGC ausgeführt werden.
Die Herausforderung: JavaScript
Die Berechnungsmaschine von Google Tabellen wurde ursprünglich in Java geschrieben und 2006 eingeführt. In den Anfangszeiten des Produkts wurden alle Berechnungen auf dem Server durchgeführt. Seit 2013 wird die Engine jedoch mit JavaScript im Browser ausgeführt. Ursprünglich wurde dies über das Google Web Toolkit (GWT) und später über den Java to Closure JavaScript-Transpiler (J2CL) erreicht. Die JavaScript-Berechnungs-Engine wird in einem Webworker ausgeführt und kommuniziert über einen MessageChannel
mit dem Hauptthread.
Die Migration von Nutzern vom Server zur JavaScript-Version der Berechnungsmaschine (und später von GWT zu J2CL) war ein großer Schritt, der sorgfältig validiert werden musste. Damit die JavaScript-Berechnungsmaschine genau dieselben Ergebnisse wie die Java-Version liefert, hat das Google Tabellen-Team einen internen Validierungsmechanismus entwickelt. Mit diesem Mechanismus können viele Tabellen verarbeitet und überprüft werden, ob die Ergebnisse in mehreren Versionen der Berechnungsmaschine identisch sind. Das Google Tabellen-Team verwendet dieses Tool regelmäßig, um Änderungen an Google Tabellen zu validieren. Das Team verglich jedoch nicht nur die Ergebnisse dieser Berechnungen, sondern auch die Leistung von JavaScript auf dem Client und Java auf dem Server. Er stellte fest, dass die JavaScript-Version der Berechnungsmaschine mehr als dreimal langsamer als die Java-Version war.
Warum ist JavaScript langsamer als Java?
JavaScript ist für eine dynamisch und loosy-typed Programmiersprache sehr schnell. Durch umfangreiche Investitionen in Just-in-Time-Compiler (JIT) wie Maglev, Sparkplug und Turbofan in den letzten 15 Jahren konnte die Leistung von JavaScript gesteigert werden. Die losen Typen und das dynamische Verhalten von JavaScript erschweren es jedoch JIT-Compilern, optimalen Code zu generieren. JavaScript hinkt also beim Rohdurchsatz noch hinter Sprachen wie Java und C++ hinterher. TypeScript bietet JavaScript Typsicherheit. Diese Typinformationen sollen die Entwicklung jedoch erleichtern und nicht die Art von Garantien bieten, die Compiler zum Generieren von optimalem Code benötigen. In Fällen wie Google Tabellen, bei denen die Berechnung großer Tabellen mehrere Sekunden dauern kann, ist JavaScript zwar schnell, aber nicht schnell genug.
Die Lösung: WasmGC
WasmGC ist eine Erweiterung der bestehenden WebAssembly-Spezifikation, die die Primitiven hinzufügt, die zum Kompilieren von Sprachen mit Garbage Collection (z. B. Java) erforderlich sind. WasmGC fügt beispielsweise Anweisungen zum Definieren von Typen und zum Zuweisen von Datenstrukturen hinzu, die durch Garbage Collection verwaltet werden. WasmGC wird für Sprachen mit Garbage Collection das tun, was Wasm für C++ getan hat (z. B. Photoshop oder Google Earth): Sie werden mit nahezu nativer Geschwindigkeit im Web verfügbar gemacht. Wir bei Google sind der Meinung, dass WasmGC aufgrund der Beliebtheit von Sprachen mit Garbage Collection noch wirkungsvoller sein kann als Wasm.
Google Workspace-Partner mit Chrome
Die WasmGC MVP-Entwurfsspezifikation wurde 2019 veröffentlicht. Ende 2020 haben Google Workspace und Chrome gemeinsam WasmGC mit der Berechnungsmaschine von Google Tabellen bewertet. Das Multi-Plattform-Team von Workspace verfügt über umfangreiche Erfahrung beim Erstellen und Optimieren von Compilern und Translatoren. Google Tabellen, ein Teil von Workspace, wurde als idealer Kandidat für die Bewertung von WasmGC identifiziert: Es ist leistungssensitiv und verfügt über robuste Mechanismen zur Leistungs- und Richtigkeitsvalidierung. Chrome hat das V8, das die WasmGC-Laufzeit entwickelt und optimiert, sowie Mitwirkende an Binaryen, die AOT-Optimierungen (Ahead-of-Time) erstellen. Chrome und Workspace bieten alle erforderlichen Fachkenntnisse, um eine WasmGC-Toolchain zu erstellen und zu optimieren. Google Tabellen ist dabei ein ideales Testfeld.
Der erste Prototyp
Mitte 2021 hatten die Teams einen funktionierenden Java-zu-WasmGC-Compiler. Gegen Ende desselben Jahres hatten sie eine Prototypversion von Google Tabellen, die als WasmGC ausgeführt wurde und Berechnungen durchführte. Dabei stieß das Team auf viele Herausforderungen. Die Tools zum Profiling und Erstellen von Heap-Dumps gab es nicht und mussten entwickelt werden. Die vorhandene Implementierung basierte auf vielen JavaScript-Bibliotheken, für die Ersatz für WasmGC gefunden oder geschrieben werden musste. Die Validierung der Korrektheit der Wasm-Berechnungsmaschine war aufgrund der experimentellen Natur der Spezifikation, des Compilers und der neuen Bibliotheken zeitaufwendig. Aber die Validierungsmechanismen von Google Tabellen waren wieder einmal äußerst hilfreich. Die Teams haben es schließlich geschafft, alles zum Laufen zu bringen, und Anfang 2022 wurden die ersten Leistungsdaten erfasst.
Zusätzliche Optimierungen
Die ursprüngliche Version von Sheets Wasm war bei Berechnungen etwa doppelt so langsam wie JavaScript. Das ist jedoch kein schlechtes Ergebnis für eine neue Spezifikation, einen neuen Compiler und mehrere neue Bibliotheken. Ab diesem Zeitpunkt begann das Google Tabellen-Team mit der Optimierung. Bei der Optimierung wurden einige Kategorien identifiziert:
- Kernoptimierungen, die bereits in der Java Virtual Machine (JVM) und in V8 vorhanden waren, wurden übernommen.
- Hochoptimierte Browser-APIs verwenden
- JavaScript-spezifische Codierungsmuster wurden entfernt.
Zuerst musste das Google Tabellen-Team Optimierungen nachbilden, die bereits in anderen Toolchains vorhanden sind. Das beste Beispiel hierfür ist die Optimierung des virtuellen Methoden-Dispatching, das schon lange von der JVM und V8 optimiert wurde, für WasmGC aber nicht verfügbar war. Durch die Implementierung von spekulativem Inline-Einfügen und Devirtualisierung – zwei sehr gängige Optimierungen – wurde die Berechnungszeit in Chrome um etwa 40% verkürzt.
Zweitens gibt es Fälle, in denen Browser-APIs von optimierten nativen Implementierungen unterstützt werden, mit denen Wasm nur schwer mithalten kann. Strings und reguläre Ausdrücke sind zwei gute Beispiele. Insbesondere bei regulären Ausdrücken konnte das Team eine fast 100-fache Beschleunigung der regulären Ausdrucksoperationen erzielen, als es von re2j (in WasmGC kompiliert) zur RegExp
-Browser-API in Chrome wechselte, die jeden regulären Ausdruck in seinen eigenen Maschinencode kompilieren kann.
Außerdem stellte das Team fest, dass die Codebasis durch jahrelange Optimierungen zu sehr auf JavaScript ausgerichtet war. So gab es beispielsweise eine Hauptdatenstruktur in Google Tabellen, die die Grenzen zwischen Arrays und Maps verwischte. Dies ist in JavaScript effizient, da dort sparse Arrays automatisch als Maps modelliert werden, aber auf anderen Plattformen langsam. Daher musste der Code plattformunabhängiger neu geschrieben werden. Das ist ein weiterer Vorteil von WebAssembly: Es erleichtert es, mit einer plattformübergreifenden Anwendung eine gute Leistung im Web zu erzielen. Sie müssen Ihre gesamte Anwendung nicht an die Eigenheiten von JavaScript anpassen.
Das Endergebnis
Nach all diesen Optimierungen ist die Berechnungsleistung der finalen WasmGC-Version von Google Tabellen etwa doppelt so hoch wie bei JavaScript. Das entspricht einer vierfachen Verbesserung gegenüber der ursprünglichen WasmGC-Version.
Fazit
WasmGC ist eine leistungsstarke Technologie, die die Entwicklung von Webanwendungen revolutionieren könnte. Wir hoffen, dass WasmGC in den kommenden Jahren weiterentwickelt wird, um Multithreading mit gemeinsam genutztem Arbeitsspeicher zu unterstützen und die Leistung bei einem einzelnen Thread weiter zu verbessern. Wir empfehlen allen Webentwicklern, WasmGC für ihr nächstes Hochleistungsprojekt zu verwenden. Machen Sie mit uns das Web schneller und flüssiger.
Danksagungen
Vielen Dank an die folgenden Personen, die an der Implementierung von WasmGC und an dieser Fallstudie mitgewirkt haben: Diwas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Asim Fazal, Michael Frederick, Goktug Gokdogan, Janice Gu, Adam Klein, Manos Koukoutos, Jakob Kummerow, Matthias Liedtke, Thomas Lively, Roberto Lublinerman, Vishrut Mehta, Thomas Nattestad, Josh Pearlstein, Joaquim Perotti, Chris Ruenes, Steven Saviano, Derek Schuff, Tim Sears, Michael Thomas, Yuan Tian, Philipp Weis, Mason Wu, Alon Zakai und Emanuel Ziegler.