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

Google Tabellen ist eines der ersten Produkte bei Google, das WasmGC in Chrome verwendet. Die Umstellung wurde 2022 angekündigt und die Teams von Google Tabellen und Chrome arbeiteten an Standardisierung, Entwicklung und Tools, um in Echtzeit Feedback zu Optimierungen zu geben. Diese Partnerschaft hat als Grundlage dafür geschaffen, wie Entwicklerteams bei Google effektiv mit Chrome zusammenarbeiten können, um mehr Google-Apps unter WasmGC auszuführen.

Die Herausforderung: JavaScript

Die Berechnungs-Engine von Google Tabellen wurde ursprünglich in Java geschrieben und 2006 eingeführt. In den frühen Tagen des Produkts fand die gesamte Berechnung auf dem Server statt. Seit 2013 wird die Suchmaschine jedoch mit JavaScript im Browser ausgeführt. Dies wurde ursprünglich mit dem Google Web Toolkit (GWT) und später mit dem Java to Closure JavaScript Transpiler (J2CL) umgesetzt. Das JavaScript-Berechnungsmodul wird in einem Web Worker ausgeführt und kommuniziert über einen MessageChannel mit dem Hauptthread.

Die Migration der Nutzer vom Server zur JavaScript-Version der Berechnungs-Engine (und später von GWT zu J2CL) war ein umfangreiches Unterfangen, das eine sorgfältige Validierung erforderte. Um sicherzustellen, dass die JavaScript-Berechnungs-Engine genau dieselben Ergebnisse wie die Java-Version lieferte, entwickelte das Google Tabellen-Team einen internen Validierungsmechanismus. Mit diesem Mechanismus kann ein großer Korpus von Tabellenblättern verarbeitet und validiert werden, dass die Ergebnisse bei mehreren Versionen der Berechnungs-Engine identisch sind. Das Google Tabellen-Team verwendet dieses Tool regelmäßig, um Änderungen an Google Tabellen zu validieren. Das Team hat jedoch nicht nur die Ergebnisse dieser Berechnungen verglichen, sondern auch die Leistung von JavaScript auf dem Client und Java auf dem Server. Dabei stellte sich heraus, 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 locker typisierte, dynamische Sprache schnell. In den letzten 15 Jahren haben hohe Investitionen in Just-in-Time-Compiler (z. B. Maglev, Sparkplug und Turbofan) die Leistung von JavaScript gesteigert. Die losen Typen und das dynamische Verhalten von JavaScript erschweren es jedoch JIT-Compilern, optimalen Code zu generieren. Das bedeutet, dass JavaScript im Hinblick auf den Rohdurchsatz immer noch hinter Sprachen wie Java und C++ zurückliegt. Mit TypeScript wird JavaScript um die Typsicherheit erweitert. Diese Typinformationen sollen jedoch die Entwicklung erleichtern und nicht die Garantien bieten, die Compiler zum Generieren von optimalem Code benötigen. In Fällen wie Google Tabellen, in denen die Berechnung großer Tabellen mehrere zehn Sekunden in Anspruch nimmt, ist JavaScript zwar schnell, aber nicht schnell genug.

Die Lösung: WasmGC

WasmGC ist eine Erweiterung der bestehenden WebAssembly-Spezifikation, mit der die Primitiven hinzugefügt werden, die zum Kompilieren von Sprachen für die automatische Speicherbereinigung (z. B. Java) erforderlich sind. WasmGC fügt beispielsweise Anweisungen zum Definieren von Typen und zum Zuweisen von automatisch erfassten Datenstrukturen hinzu. WasmGC ist bereit, für die automatische Speicherbereinigung dasselbe zu tun, was Wasm für C++ getan hat (z. B. Photoshop oder Google Earth), um sie mit nahezu nativer Geschwindigkeit ins Web zu bringen. Wir bei Google sind davon überzeugt, dass WasmGC aufgrund der Beliebtheit von automatisch bereinigten Sprachen noch wirkungsvoller sein kann als Wasm.

Google Workspace arbeitet mit Chrome zusammen

Der Entwurf der WasmGC-MVP-Spezifikation wurde 2019 veröffentlicht. Ende 2020 haben sich Google Workspace und Chrome zusammengetan, um WasmGC mithilfe der Berechnungs-Engine für Google Tabellen zu evaluieren. Das plattformübergreifende Team von Workspace verfügt über umfassendes Fachwissen, um Compiler und Transpiler zu entwickeln und zu optimieren. Google Tabellen, 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 für Chrome kümmert sich um die Entwicklung und Optimierung der WasmGC-Laufzeit und leistet Beiträge zu Binaryen, um Vorab-Optimierungen (AOT) zu entwickeln. Bei Chrome und Workspace haben wir das nötige Fachwissen, um eine WasmGC-Toolchain zu erstellen und zu optimieren – mit Google Tabellen als idealer Testplattform.

Der erste Prototyp

Mitte 2021 hatten die Teams einen funktionierenden Java-zu-WasmGC-Compiler. Gegen Ende desselben Jahres hatte das Unternehmen einen Prototyp von Google Tabellen, das als WasmGC ausgeführt wurde und Berechnungen durchführte. Dabei stößt sie auf viele Herausforderungen. Es gab keine Tools zum Erstellen von Profilen und zum Erfassen von Heap-Dumps. Die bestehende Implementierung basierte auf vielen JavaScript-Bibliotheken, für die Ersatzdateien für WasmGC gefunden oder geschrieben werden mussten. Die Validierung der Richtigkeit der Wasm-Berechnungs-Engine war aufgrund der experimentellen Natur der Spezifikation, des Compilers und neuer Bibliotheken ein zeitaufwendiger Aufwand. Aber die Validierungsmechanismen von Google Tabellen waren wieder sehr hilfreich. Am Ende kam alles zum Erfolg. Die Leistungsdaten wurden Anfang 2022 bereitgestellt.

Zusätzliche Optimierungen

In der ersten Version von Wasm für Google Tabellen war die Berechnungsleistung etwa doppelt so langsamer wie mit JavaScript. Dies ist jedoch kein schlechtes Ergebnis für eine neue Spezifikation, einen neuen Compiler und mehrere neue Bibliotheken. Das Google Tabellen-Team begann dann mit der Optimierung. Unter den gefundenen Optimierungen wurden mehrere Kategorien ermittelt:

  • Replizieren von Kernoptimierungen, die bereits in der Java Virtual Machine (JVM) und in V8 vorhanden waren.
  • Hochoptimierte Browser-APIs verwenden
  • JavaScript-spezifische Codierungsmuster werden entfernt.

Zuerst musste das Google Tabellen-Team Optimierungen replizieren, die bereits in anderen Toolchains vorhanden waren. Das beste Beispiel dafür ist die Optimierung des virtuellen Methodenversands, der schon lange von der JVM und V8 optimiert wurde, für WasmGC aber noch nichts gab. Durch die Implementierung von spekulativem Inlining und Devirtualisierung – zwei sehr gängigen Optimierungen –, verkürzt sich die Rechenzeit in Chrome um etwa 40 %.

Zweitens gibt es Fälle, in denen Browser-APIs von optimierten nativen Implementierungen unterstützt werden, die mit Wasm kaum mithalten können. Zeichenfolgen und reguläre Ausdrücke sind zwei gute Beispiele. Insbesondere mit regulären Ausdrücken konnte das Team die Vorgänge für reguläre Ausdrücke beim Wechsel von re2j (in WasmGC kompiliert) zur RegExp Browser-API in Chrome, die jeden regulären Ausdruck in seinen eigenen Computercode kompilieren kann, fast 100-mal beschleunigen.

Zuletzt stellte sich heraus, dass die Codebasis aufgrund der jahrelangen Optimierung zu stark an JavaScript angepasst war. Beispielsweise hatte es eine grundlegende Datenstruktur in Google Tabellen, die die Linien zwischen Arrays und Karten unkenntlich machte. Dies ist effizient in JavaScript, das dünnbesetzte Arrays automatisch als Karten modelliert, auf anderen Plattformen jedoch langsam. Daher mussten sie den Code auf eine plattformunabhängigere Art und Weise neu schreiben. Das ist eine weitere Sache, die das Team an WebAssembly schätzt: Es erleichtert es plattformübergreifenden Anwendungen, eine gute Leistung im Web zu erzielen. Sie müssen nicht Ihre gesamte Anwendung an die Besonderheiten von JavaScript anpassen.

Das Endergebnis

Nach all diesen Optimierungen erreicht die endgültige WasmGC-Version von Google Tabellen eine Berechnungsleistung etwa doppelt so schnell wie JavaScript, was eine Vervierfachung gegenüber dem Startpunkt der ursprünglichen WasmGC-Version darstellt.

Fazit

WasmGC ist eine leistungsstarke Technologie, die das Potenzial hat, die Art und Weise, wie Entwickler Webanwendungen erstellen, zu verbessern. Wir hoffen, dass WasmGC in den kommenden Jahren Multithreading mit gemeinsam genutztem Arbeitsspeicher unterstützen und die Leistung von Single-Threaded weiter verbessern kann. Wir empfehlen allen Webentwicklern, für ihr nächstes leistungsstarkes Projekt die Verwendung von WasmGC in Betracht zu ziehen. Machen Sie mit uns gemeinsam das Web zu einem schnelleren und flüssigeren Ort!

Danksagungen

Wir bedanken uns bei allen, die an der WasmGC-Implementierung und an dieser Fallstudie mitgearbeitet haben: Diwas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Asim Fazal, Michael Frederick, Goktug Gokdogan, Janice Gurda der Adam Klein, Thomas Koukoutos.