Warum Google Tabellen seinen Berechnungs-Worker von JavaScript zu WasmGC portiert hat

Google Sheets ist eines der ersten Produkte bei Google, in denen WasmGC in Chrome verwendet wird. Die Umstellung wurde 2022 angekündigt. Die Teams von Google Sheets und Chrome haben bei der Standardisierung, Entwicklung und den Tools zusammengearbeitet, um Echtzeit-Feedback zu Optimierungen zu ermöglichen. Diese Partnerschaft hat gezeigt, wie Engineering-Teams bei Google effektiv mit Chrome zusammenarbeiten können, damit mehr Google-Apps auf WasmGC ausgeführt werden.

Herausforderung: JavaScript

Die Google Tabellen-Berechnungs-Engine wurde ursprünglich in Java geschrieben und 2006 eingeführt. In den Anfangstagen des Produkts wurden alle Berechnungen auf dem Server durchgeführt. Seit 2013 wird die Engine jedoch im Browser mit JavaScript ausgeführt. Dies wurde ursprünglich über das Google Web Toolkit (GWT) und später über den Java-zu-Closure-JavaScript-Transpiler (J2CL) erreicht. Die JavaScript-Berechnungs-Engine wird in einem Web Worker ausgeführt und kommuniziert über einen MessageChannel mit dem Hauptthread.

Die Migration von Nutzern vom Server zur JavaScript-Version der Berechnungs-Engine (und später von GWT zu J2CL) war ein großes Unterfangen, das eine sorgfältige Validierung erforderte. Damit die JavaScript-Berechnungs-Engine genau dieselben Ergebnisse wie die Java-Version liefert, hat das Sheets-Team einen internen Validierungsmechanismus entwickelt. Mit diesem Mechanismus kann eine große Menge von Tabellenblättern verarbeitet und überprüft werden, ob die Ergebnisse zwischen mehreren Versionen der Berechnungs-Engine identisch sind. Das Sheets-Team verwendet dieses Tool regelmäßig, um Änderungen an Sheets zu validieren. Das Team hat aber nicht nur die Ergebnisse dieser Berechnungen verglichen, sondern auch die Leistung von JavaScript auf dem Client und Java auf dem Server. Sie stellten fest, dass die JavaScript-Version der Berechnungs-Engine mehr als dreimal langsamer war als die Java-Version.

Warum ist JavaScript langsamer als Java?

JavaScript ist für eine lose typisierte, dynamische Sprache schnell. Durch die hohen Investitionen in JIT-Compiler (z. B. Maglev, Sparkplug und Turbofan) in den letzten 15 Jahren wurde die Leistung von JavaScript gesteigert. Die losen Typen und das dynamische Verhalten von JavaScript erschweren es JIT-Compilern jedoch, optimalen Code zu generieren. Das bedeutet, dass JavaScript in Bezug auf den Rohdurchsatz immer noch hinter Sprachen wie Java und C++ zurückbleibt. TypeScript fügt JavaScript Typsicherheit hinzu. Diese Typinformationen sollen die Entwicklung erleichtern und nicht die Art von Garantien bieten, die Compiler benötigen, um optimalen Code zu generieren. In Fällen wie Google Tabellen, in denen die Berechnung großer Tabellenkalkulationen Dutzende von 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 zum Kompilieren von Garbage-Collection-Sprachen (z. B. Java) erforderlichen Primitiven hinzufügt. WasmGC fügt beispielsweise Anweisungen zum Definieren von Typen und zum Zuweisen von Garbage-Collection-Datenstrukturen hinzu. WasmGC wird für Sprachen mit Garbage Collection das leisten, was Wasm für C++ geleistet hat (z. B. Photoshop oder Google Earth): Sie werden mit nahezu nativer Geschwindigkeit im Web ausgeführt. Wir bei Google sind der Meinung, dass WasmGC aufgrund der Beliebtheit von Sprachen mit Garbage Collection noch mehr Potenzial hat als Wasm.

Google Workspace-Partner mit Chrome

Die WasmGC MVP-Spezifikation wurde 2019 veröffentlicht. Ende 2020 haben Google Workspace und Chrome gemeinsam WasmGC mit der Tabellenkalkulations-Engine von Google Tabellen getestet. Das Multiplattform-Team von Workspace verfügt über umfangreiches Know-how in der Entwicklung und Optimierung von Compilern und Transpilern. Sheets, ein Teil von Workspace, wurde als idealer Kandidat für die Bewertung von WasmGC identifiziert: Es ist leistungsabhängig und verfügt über robuste Mechanismen zur Validierung von Leistung und Richtigkeit. Das V8-Team von Chrome entwickelt und optimiert die WasmGC-Laufzeit. Außerdem gibt es Mitwirkende bei Binaryen, die AOT-Optimierungen (Ahead-of-Time) entwickeln. Zwischen Chrome und Workspace ist das gesamte Know-how vorhanden, das zum Erstellen und Optimieren einer WasmGC-Toolchain erforderlich ist. Google Sheets ist dabei ein ideales Testfeld.

Der erste Prototyp

Mitte 2021 hatten die Teams einen funktionierenden Java-zu-WasmGC-Compiler. Gegen Ende des Jahres hatten sie eine Prototypversion von Google Sheets, die als WasmGC ausgeführt wurde und Berechnungen durchführte. Dabei stießen sie auf viele Herausforderungen. Es gab keine Tools zum Erstellen von Profilen und Heap-Dumps, die erst entwickelt werden mussten. Die vorhandene Implementierung basierte auf vielen JavaScript-Bibliotheken, für die Ersatz gefunden oder für WasmGC geschrieben werden musste. Die Validierung der Richtigkeit der Wasm-Berechnungs-Engine war aufgrund des experimentellen Charakters der Spezifikation, des Compilers und der neuen Bibliotheken zeitaufwendig. Die Validierungsmechanismen von Google Tabellen waren jedoch wieder einmal äußerst hilfreich. Die Teams haben es schließlich geschafft und Anfang 2022 wurden die ersten Leistungsdaten erfasst.

Zusätzliche Optimierungen

In der ursprünglichen Version von Sheets Wasm war die Berechnungsleistung etwa zweimal langsamer als bei JavaScript. Das ist jedoch kein schlechtes Ergebnis für eine neue Spezifikation, einen neuen Compiler und mehrere neue Bibliotheken. Ab diesem Zeitpunkt begann das Sheets-Team mit der Optimierung. Bei den Optimierungen, die sie gefunden haben, haben sich einige Kategorien herauskristallisiert:

  • Replikation von Kernoptimierungen, die bereits in der Java Virtual Machine (JVM) und in V8 vorhanden waren.
  • Hochgradig optimierte Browser-APIs verwenden.
  • Entfernen von JavaScript-spezifischen Codemustern

Zuerst musste das Sheets-Team Optimierungen replizieren, die bereits in anderen Toolchains vorhanden sind. Das beste Beispiel hierfür ist die Optimierung des virtuellen Methodenversands, der von der JVM und V8 schon lange optimiert wird, für WasmGC aber noch nicht existierte. Durch die Implementierung von spekulativer Inline-Erstellung und Devirtualisierung – zwei sehr häufige Optimierungen – konnte die Berechnungszeit in Chrome um etwa 40% verkürzt werden.

Zweitens gibt es Fälle, in denen Browser-APIs durch optimierte native Implementierungen unterstützt werden, mit denen Wasm nur schwer konkurrieren kann. Gute Beispiele hierfür sind Strings und reguläre Ausdrücke. Konkret konnte das Team durch die Umstellung von re2j (kompiliert zu WasmGC) auf die Browser-API RegExp in Chrome, die jeden regulären Ausdruck in eigenen Maschinencode kompilieren kann, die Geschwindigkeit von Operationen mit regulären Ausdrücken um das Hundertfache steigern.

Außerdem stellten sie fest, dass die Codebasis durch jahrelange Optimierung zu stark auf JavaScript ausgerichtet war. So hatten sie beispielsweise eine zentrale Datenstruktur in Google Tabellen, die die Grenzen zwischen Arrays und Maps verwischte. In JavaScript, wo dünnbesetzte Arrays automatisch als Maps modelliert werden, ist das effizient, auf anderen Plattformen jedoch langsam. Daher mussten sie den Code plattformunabhängiger gestalten. Das ist ein weiterer Vorteil von WebAssembly: Es erleichtert die Entwicklung von Multiplattformanwendungen, die im Web eine gute Leistung erzielen. Sie müssen Ihre gesamte Anwendung nicht an die Besonderheiten von JavaScript anpassen.

Das Endergebnis

Nach all diesen Optimierungen erreicht die endgültige WasmGC-Version von Google Tabellen eine Berechnungsleistung, die etwa doppelt so schnell wie JavaScript ist. Das entspricht einer Vervierfachung gegenüber der ursprünglichen WasmGC-Version.

Fazit

WasmGC ist eine leistungsstarke Technologie, die das Potenzial hat, die Art und Weise, wie Entwickler Webanwendungen erstellen, zu revolutionieren. Wir bei Google hoffen, dass WasmGC in den kommenden Jahren weiterentwickelt wird, um Shared Memory Multithreading zu unterstützen und die Single-Thread-Leistung weiter zu verbessern. Wir empfehlen allen Webentwicklern, WasmGC für ihr nächstes leistungsstarkes Projekt in Betracht zu ziehen. Machen Sie mit uns das Web schneller und reibungsloser!

Danksagungen

Vielen Dank an alle, die an der WasmGC-Implementierung und 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.