為何 Google 試算表將其計算工作站從 JavaScript 移植到 WasmGC

Google 試算表是 Google 在 Chrome 上率先使用 WasmGC 的產品之一。這是 2022 年宣布的遷移計畫,Google 試算表和 Chrome 團隊與標準化、工程和工具合作,針對最佳化作業提供即時意見回饋。這項合作計畫對於 Google 工程團隊如何與 Chrome 有效合作,讓他們能在 WasmGC 上執行更多 Google 應用程式。

挑戰:JavaScript

Google 試算表的計算引擎最初是以 Java 編寫,並於 2006 年推出。在產品推出初期,所有計算作業都在伺服器上進行。不過,自 2013 年起,引擎已經使用 JavaScript 在瀏覽器中執行。這項作業最初是透過 Google Web Toolkit (GWT),之後透過 Java 到 Closure JavaScript 轉譯器 (J2CL)。JavaScript 計算引擎會在網路工作站中執行,並使用 MessageChannel 與主執行緒通訊。

將使用者從伺服器遷移至 JavaScript 版本的計算引擎 (以及之後從 GWT 遷移至 J2CL),這是必須謹慎驗證的主要原因。為了確保 JavaScript 計算引擎產生的結果與 Java 版本完全相同,Google 試算表團隊開發了內部驗證機制。這項機制可處理大型工作表語料庫,並驗證計算引擎的多個版本之間的結果是否相同。Google 試算表團隊會定期使用這項工具驗證 Google 試算表的變更內容。不過,團隊不只比較這些計算結果,還比較了用戶端與伺服器 Java 之間的效能。他們發現 JavaScript 版本的計算引擎,比 Java 版本的慢了 3 倍以上。

為什麼 JavaScript 比 Java 慢?

JavaScript 針對鬆散類型的動態語言快速載入。過去 15 年來,MaglevSparkplugTurbofan) 投入大量心力在及時發展型編譯器,因此提升了 JavaScript 的執行效能。然而,JavaScript 的類型和動態行為較不理想,因此 JIT 編譯器很難產生最佳程式碼。這表示 JavaScript 仍會落後於 Java 和 C++ 等語言,提供原始處理量。TypeScript 可提升 JavaScript 類型安全性,但這類類型資訊旨在簡化開發程序,而不是提供編譯器需要產生最佳程式碼所需的保證。在 Google 試算表這類情況下,大型試算表可能需要數十秒才能完成計算,這時 JavaScript 速度很快,但速度還不夠快。

解決方案:WasmGC

WasmGC 是現有 WebAssembly 規格的 擴充功能,可加入編譯垃圾收集語言 (例如 Java) 所需的基本功能。舉例來說,WasmGC 新增了定義類型及分配垃圾收集資料結構的操作說明。WasmGC 預計將 Wasm 針對 C++ (例如 PhotoshopGoogle 地球) 進行垃圾收集,以便以近乎原生的速度連上網路。Google 相信,由於垃圾收集的語言越來越受歡迎,我們相信 WasmGC 的影響力甚至比 Wasm 更出色。

Google Workspace 與 Chrome 攜手合作

WasmGC MVP 草稿規格於 2019 年發布。2020 年底,Google Workspace 和 Chrome 攜手合作,使用試算表計算引擎評估 WasmGC。Workspace 的多平台團隊具備豐富的專業知識,能建立及最佳化編譯器和轉譯器。Google 試算表是 Workspace 中的一項服務,是評估 WasmGC 的理想選擇:它不僅注重效能,也具備健全的效能和正確性驗證機制。Chrome 擁有 V8 團隊打造及最佳化 WasmGC 執行階段,以及對 Binaryen 提供內容貢獻者,協助他們預先 (AOT) 最佳化調整。無論是 Chrome 與 Workspace,還是具備建構和最佳化 WasmGC 工具鍊所需的專業知識,Google 試算表都是理想的測試平台。

第一個原型

在 2021 年中前,團隊打造了一個 Java 至 WasmGC 編譯器的工作。今年年底前,他們以 WasmGC 的形式執行 Google 試算表的原型版本,並進行計算。他們一路走來,他們克服了許多挑戰。不存在剖析及擷取記憶體快照資料的工具,因此需要建構。現有的實作方式仰賴許多 JavaScript 程式庫,而這些程式庫必須找到或編寫供 WasmGC 取代的替代程式庫。由於規格、編譯器和新程式庫屬於實驗性質,因此驗證 Wasm 計算引擎的正確性會耗費大量時間。但 Google 試算表的驗證機制過去一直都很有幫助。團隊最終終於順利獲得一切,成效資料也將於 2022 年初提供。

其他最佳化設定

試算表 Wasm 最初版的計算效能大約比 JavaScript 低了兩倍。不過,對於新規格、新編譯器和多個新程式庫而言,這並非不良結果。此時,Google 試算表團隊開始進行最佳化。他們根據這些改善內容發現以下幾個類別:

  • 複製 Java 虛擬機器 (JVM) 和 V8 中既有的核心最佳化。
  • 使用高度最佳化的瀏覽器 API。
  • 移除 JavaScript 特有的編碼模式。

首先,Google 試算表團隊需要複製其他工具鍊中現有的最佳化內容。最好的例子是最佳化虛擬方法分派,這個方法已由 JVM 和 V8 最佳化,但 WasmGC 並沒有最佳化。在 Chrome 中導入推測內嵌去虛擬化功能 (兩種很常見的最佳化做法),將計算時間縮短約 40%。

第二,有時候瀏覽器 API 均由最佳化原生實作支援,因此難以與 Wasm 競爭。字串和規則運算式就是兩個很好的範例。具體來說,在規則運算式中,團隊從 re2j (編譯至 WasmGC) 切換至 RegExp 瀏覽器 API 時,規則運算式作業的速度提升將近 100 倍,這項工具可將各個規則運算式編譯成各自的機器碼。

最後,他們發現數年的最佳化導致程式碼集過度適應 JavaScript。舉例來說,這些公司在 Google 試算表中使用核心資料結構,模糊處理了陣列與對應之間的線條。這在 JavaScript 中很有效率,可以自動將稀疏陣列建立成對應,但在其他平台上的執行速度較慢。因此他們必須以更適用於平台的方式重新編寫程式碼。WebAssembly 是開發團隊的另一項特色:這個平台可讓多平台應用程式更輕鬆地在網路上展現良好效能。您不需要將整個應用程式繫結至 JavaScript 的用語。

最終結果

完成上述所有最佳化調整後,Google 試算表的最終 WasmGC 版本計算效能大約是 JavaScript 的兩倍,代表從 WasmGC 初始版本起算,效能提升了 4 倍。

結論

WasmGC 是一項強大技術,可望推動開發人員建構網頁應用程式的方式。未來幾年內,Google 希望能看到 WasmGC 進一步支援共用記憶體多執行緒,並進一步改善單一執行緒效能。我們建議所有網頁程式開發人員考慮使用 WasmGC 推動下一個高效能專案。快來加入我們,讓網路世界變得更快、更順暢!

特別銘謝