Google スプレッドシートが計算ワーカーを JavaScript から WasmGC に移植した理由

Google スプレッドシートは、Chrome で WasmGC を使用する Google 初のプロダクトの 1 つです。この移行は 2022 年に発表され、Google スプレッドシートと Chrome のチームは標準化、エンジニアリング、ツールに関して連携し、最適化に関するフィードバックをリアルタイムで提供しました。このパートナーシップは、Google のエンジニアリング チームが Chrome を効果的に連携させ、より多くの Google アプリを WasmGC で実行できるようにする前例となります。

Google スプレッドシートの計算エンジンは元々 Java で記述され、2006 年にリリースされました。開発の初期段階には、すべての計算がサーバーで行われていました。ただし、2013 年からは JavaScript を使用してブラウザ内でエンジンを実行するようになりました。これは元々、Google Web Toolkit(GWT)を介して行われ、その後 Java to Closure JavaScript Transpiler(J2CL)を使用して実現されていました。JavaScript 計算エンジンはウェブ ワーカーで実行され、MessageChannel を使用してメインスレッドと通信します。

ユーザーをサーバーから JavaScript バージョンの計算エンジンに移行する(後に GWT から J2CL に移行する)ことは、慎重な検証を必要とする重要な作業でした。JavaScript 計算エンジンが Java バージョンとまったく同じ結果を確実に生成するように、Google スプレッドシートのチームは内部検証メカニズムを開発しました。このメカニズムでは、大規模なシートのコーパスを処理し、計算エンジンの複数のバージョン間で結果が同じであることを検証できます。Google スプレッドシート チームは、定期的にこのツールを使用し、スプレッドシートに加えられた変更を検証しています。しかし、チームは計算結果を比較するだけでなく、クライアント上の JavaScript とサーバー上の Java のパフォーマンスも比較しました。その結果、JavaScript 版の計算エンジンは Java 版より 3 倍以上低速であることがわかりました。

JavaScript が Java よりも遅いのはなぜですか?

JavaScript は、ゆるく型付けされた動的な言語に対して高速です。過去 15 年間、ジャストインタイム(JIT)コンパイラ(MaglevSparkplugTurbofan など)に多額の投資を行うことで、JavaScript のパフォーマンスが向上しています。しかし、JavaScript の型が緩く、動作が動的であるため、JIT コンパイラが最適なコードを生成することは困難です。つまり、JavaScript の純粋なスループットについては、Java や C++ などの言語より劣っています。TypeScript は JavaScript に型安全性を追加しますが、その型情報は開発を容易にするためのものであり、コンパイラが最適なコードを生成するために必要な保証を提供するものではありません。Google スプレッドシートのように、大きなスプレッドシートの計算には数十秒かかることがあるため、JavaScript は高速ですが、十分とは言えません。

解決策: WasmGC

WasmGC は既存の WebAssembly 仕様の拡張機能で、ガベージ コレクション言語(Java など)のコンパイルに必要なプリミティブが追加されています。たとえば、WasmGC には型を定義し、ガベージ コレクション データ構造を割り当てるための命令が追加されています。WasmGC は、Wasm が C++ で行ったようにガベージ コレクション言語(PhotoshopGoogle Earth など)に対応し、ネイティブに近い速度でウェブに展開します。Google では、ガベージ コレクション言語が広く普及しているため、WasmGC が Wasm よりもさらに影響力を発揮できる可能性があると考えています。

Google Workspace と Chrome の提携

WasmGC MVP ドラフト仕様は 2019 年に公開されたものです。2020 年後半、Google Workspace と Chrome が提携し、スプレッドシートの計算エンジンを使用して WasmGC を評価しました。Workspace のマルチプラットフォーム チームは、コンパイラとトランスパイラの構築と最適化に関する豊富な専門知識を有しています。Workspace の一部であるスプレッドシートは、WasmGC の評価に理想的な候補です。パフォーマンスを重視し、堅牢なパフォーマンスと正確性の検証メカニズムを備えています。Chrome には、WasmGC ランタイムの構築と最適化を行う V8 チームと、事前(AOT)最適化を構築するための Binaryen のコントリビューターがあります。Chrome と Workspace の間には、WasmGC ツールチェーンの構築と最適化に必要な専門知識がすべて詰め込まれており、Google スプレッドシートを理想的な testbed として使用できます。

最初のプロトタイプは

2021 年半ばまでに、チームは Java から WasmGC へのコンパイラを動作させる準備が整いました。同年末にかけては、WasmGC として実行され、計算を行うための Google スプレッドシートのプロトタイプ版が完成しました。その過程で多くの課題に直面しました。プロファイリングやヒープダンプを取得するためのツールは存在せず、ビルドする必要がありました。既存の実装は多くの JavaScript ライブラリに依存しており、その代わりとなるライブラリを見つけるか、WasmGC 用に記述する必要がありました。Wasm 計算エンジンの正確性の検証は、仕様、コンパイラ、新しいライブラリの実験的な性質により、多大な時間を費やしていました。しかし、ここでもスプレッドシートの検証メカニズムは非常に役に立ちました。最終的にはチームがすべて機能し、2022 年初頭にパフォーマンス データを入手し始めました。

その他の最適化

スプレッドシート Wasm の初期バージョンでは、計算パフォーマンスが JavaScript の約 2 倍低速でした。ただし、新しい仕様、新しいコンパイラ、いくつかの新しいライブラリにとっては悪い結果ではありません。この時点から Google スプレッドシート チームは最適化を開始しました。同社が発見した最適化から、いくつかのカテゴリーが浮かび上がりました。

  • Java 仮想マシン(JVM)と V8 にすでに存在していたコア最適化を複製します。
  • 高度に最適化されたブラウザ API を使用する。
  • JavaScript 固有のコーディング パターンを削除します。

まず、スプレッドシート チームは、他のツールチェーンにすでに存在する最適化を複製する必要がありました。その最良の例は、仮想メソッド ディスパッチの最適化です。これは長い間、JVM と V8 によって最適化されてきましたが、WasmGC については何も存在しませんでした。投機的インライン化非仮想化という 2 つの非常に一般的な最適化を実装することで、Chrome での計算時間が約 40% 短縮されました。

2 つ目は、ブラウザの API が最適化されたネイティブ実装を基盤としており、Wasm の使用時に競合が難しいケースです。文字列と正規表現が良い例です。具体的には、Chrome の re2j(WasmGC にコンパイル)から RegExp ブラウザ API に切り替えると、正規表現の処理が 100 倍近く高速化されました。この API では、各正規表現を独自のマシンコードにコンパイルできます。

最後に、何年にもわたる最適化のために、コードベースが JavaScript に過剰適合していることも判明しました。たとえば、スプレッドシートの中核的なデータ構造によって、配列とマップの境界線が曖昧になっていました。これは、スパース配列をマップとして自動的にモデル化する JavaScript では効率的ですが、他のプラットフォームでは処理に時間がかかります。そのため、プラットフォームに依存しない形でコードを書き直す必要がありました。チームが WebAssembly で気に入っているもう一つの点は、マルチプラットフォーム アプリケーションがウェブ上で優れたパフォーマンスを容易に得られることです。JavaScript の特異性に合わせてアプリケーション全体を曲げる必要はありません。

最終結果

こうした最適化を経て、スプレッドシートの最終版 WasmGC は計算パフォーマンスが JavaScript の約 2 倍の速さを達成し、最初の WasmGC バージョンから 4 倍向上しています。

おわりに

WasmGC は、デベロッパーによるウェブ アプリケーションの構築方法を進歩させる可能性を秘めた強力なテクノロジーです。今後数年間、Google は WasmGC が共有メモリ マルチスレッディングをサポートし、シングル スレッドのパフォーマンスをさらに向上させることを期待しています。すべてのウェブ デベロッパーには、次回の高パフォーマンス プロジェクトで WasmGC の使用を検討することをおすすめします。より高速かつスムーズなウェブの実現にぜひご協力ください。

謝辞

WasmGC、Thomas、Er.S.O.C.O.C. の執筆にご協力いただきありがとうございます