Google Sheets에서 계산 작업자를 JavaScript에서 WasmGC로 포팅한 이유

Google Sheets는 Chrome에서 WasmGC를 사용하는 Google의 첫 제품 중 하나입니다. 2022년에 이러한 이전이 발표되었으며 Sheets와 Chrome팀은 표준화, 엔지니어링, 도구에 관해 협력하여 최적화에 대한 실시간 피드백을 제공했습니다. 이러한 파트너십은 Google 엔지니어링팀이 Chrome과 효과적으로 협력하여 WasmGC에서 더 많은 Google 앱을 실행할 수 있게 한 선례가 되었습니다.

과제: JavaScript

Google 스프레드시트 계산 엔진은 원래 Java로 작성되었으며 2006년에 출시되었습니다. 제품 초창기에는 모든 계산이 서버에서 이루어졌습니다. 그러나 2013년부터 엔진은 브라우저에서 JavaScript를 사용하여 실행되었습니다. 이 작업은 원래 Google 웹 툴킷 (GWT)을 통해 이루어졌으며, 이후 Java to Closure JavaScript 트랜스파일러 (J2CL)를 통해 수행되었습니다. JavaScript 계산 엔진은 웹 작업자에서 실행되며 MessageChannel를 사용하여 기본 스레드와 통신합니다.

사용자를 서버에서 JavaScript 버전의 계산 엔진으로 이전 (나중에 GWT에서 J2CL으로)하는 것은 신중한 검증이 필요한 중요한 작업이었습니다. Sheets 팀은 JavaScript 계산 엔진이 Java 버전과 정확히 동일한 결과를 생성할 수 있도록 내부 유효성 검사 메커니즘을 개발했습니다. 이 메커니즘은 대량의 시트 코퍼스를 처리하고 계산 엔진의 여러 버전에서 동일한 결과가 나오는지 확인할 수 있습니다. Sheets팀은 이 도구를 정기적으로 사용하여 Sheets의 변경사항을 확인합니다. 그러나 이 팀은 이러한 계산의 결과만 비교하는 것이 아니라, 클라이언트의 JavaScript와 서버의 Java 간의 성능도 비교했습니다. 그 결과, 계산 엔진의 JavaScript 버전이 Java 버전보다 3배 이상 느리다는 사실을 발견했습니다.

JavaScript가 Java보다 느린 이유는 무엇인가요?

JavaScript는 느슨하게 유형이 지정된 동적 언어에 대해 빠릅니다. 지난 15년 동안 적시 (JIT) 컴파일러 (예: Maglev, Sparkplug, Turbofan)에 막대한 투자를 하여 JavaScript의 성능이 향상되었습니다. 그러나 JavaScript의 느슨한 유형과 동적 동작으로 인해 JIT 컴파일러가 최적의 코드를 생성하기 어렵습니다. 즉, JavaScript는 원시 처리량에서 여전히 Java 및 C++와 같은 언어보다 뒤처집니다. TypeScript는 JavaScript에 유형 안전성을 추가하지만 이러한 유형 정보는 더 쉽게 개발할 수 있도록 설계되었으며 컴파일러가 최적의 코드를 생성하는 데 필요한 종류의 보장을 제공하지 않습니다. 대용량 스프레드시트를 계산하는 데 수십 초가 걸릴 수 있는 Google 시트와 같은 경우 JavaScript는 빠르지만 충분히 빠르지는 않습니다.

해결 방법: WasmGC

WasmGC는 가비지 수집된 언어 (예: Java)를 컴파일하는 데 필요한 프리미티브를 추가하는 기존 WebAssembly 사양에 대한 확장 프로그램입니다. 예를 들어 WasmGC는 유형을 정의하고 가비지로 수집된 데이터 구조를 할당하는 명령을 추가합니다. WasmGC는 C++에 대해 Wasm이 수행한 작업 (예: Photoshop 또는 Google 어스)을 가비지 컬렉션 언어에 사용할 준비가 되어 있습니다. 이는 이러한 언어를 기본 속도에 가깝게 웹에 제공하는 것입니다. Google에서는 가비지로 수집된 언어의 인기로 인해 WasmGC가 Wasm보다 더 큰 영향을 미칠 수 있다고 생각합니다.

Chrome과 협력하는 Google Workspace

WasmGC MVP 초안 사양은 2019년에 게시되었습니다. 2020년 말, Google Workspace와 Chrome은 파트너십을 통해 Sheets 계산 엔진을 사용하여 WasmGC를 평가했습니다. Workspace의 멀티플랫폼팀은 컴파일러와 트랜스파일러를 빌드하고 최적화하는 데 상당한 전문성을 보유하고 있습니다. Workspace의 일부인 Sheets는 WasmGC를 평가하기에 이상적인 후보로 확인되었습니다. 성능에 민감하며 강력한 성능 및 정확성 검증 메커니즘을 갖추고 있기 때문입니다. Chrome에는 WasmGC 런타임을 빌드하고 최적화하는 V8팀이 있으며, AOT (Ahead-of-time) 최적화 빌드를 위한 Binaryen에도 기여하고 있습니다. Chrome과 Workspace 사이에는 Google Sheets를 이상적인 테스트베드로 활용하여 WasmGC 도구 모음을 빌드하고 최적화하는 데 필요한 모든 전문성이 있습니다.

첫 번째 프로토타입은

2021년 중반 무렵에는 Java에서 WasmGC로의 컴파일러가 작동했습니다. 같은 해 말, WasmGC로 실행되는 Google 시트의 프로토타입 버전을 출시하고 계산을 수행했습니다. 그 과정에서 많은 어려움에 직면했습니다. 프로파일링과 힙 덤프를 위한 도구는 존재하지 않았으며 빌드해야 했습니다. 기존 구현은 WasmGC를 위한 대체 항목을 찾거나 작성해야 하는 많은 JavaScript 라이브러리에 의존했습니다. Wasm 계산 엔진의 정확성을 검증하는 데는 사양, 컴파일러 및 새 라이브러리의 실험적 특성으로 인해 시간이 오래 걸렸습니다. 하지만 Sheets의 유효성 검사 메커니즘은 다시 한번 매우 유용했습니다. 팀은 궁극적으로 모든 작업을 처리했고 2022년 초에 실적 데이터가 수집되기 시작했습니다.

추가 최적화

Sheets Wasm의 초기 버전은 자바스크립트보다 약 2배 느린 계산 성능을 보였습니다. 그러나 새로운 사양, 새 컴파일러 및 여러 새 라이브러리에는 나쁜 결과가 아닙니다. Sheets팀은 이 지점에서 최적화를 시작했습니다. 그 결과 다음과 같은 몇 가지 범주가 나타났습니다.

  • Java 가상 머신 (JVM) 및 V8에 이미 있었던 핵심 최적화를 복제합니다.
  • 고도로 최적화된 브라우저 API 사용
  • JavaScript 관련 코딩 패턴을 삭제합니다.

첫째, Sheets팀은 다른 도구 모음에 이미 존재하는 최적화를 복제해야 했습니다. 이에 대한 가장 좋은 예는 가상 메서드 디스패치를 최적화하는 것입니다. 가상 메서드 디스패칭은 오랫동안 JVM 및 V8에 의해 최적화되었지만 WasmGC에는 존재하지 않았습니다. 아주 일반적인 최적화 두 가지인 예측 인라인탈가상화를 구현하면 Chrome에서 계산 시간이 약 40% 빨라졌습니다.

둘째, Wasm을 사용하여서는 경쟁하기 어려운 최적화된 네이티브 구현으로 브라우저 API가 지원되는 경우가 있습니다. 문자열과 정규 표현식도 좋은 예입니다. 특히 정규 표현식을 사용하면 re2j (WasmGC로 컴파일됨)에서 RegExp 자체 정규 표현식으로 자체 정규식으로 컴파일할 수 있는

마지막으로, 수년간의 최적화로 인해 코드베이스가 JavaScript에 과적합되었다는 사실을 발견했습니다. 예를 들어 Sheets에는 배열과 지도 사이의 선을 흐리게 처리하는 핵심 데이터 구조가 있었습니다. 이는 희소 배열을 맵으로 자동 모델링하는 JavaScript에서는 효율적이지만 다른 플랫폼에서는 느립니다. 그래서 플랫폼에 구애받지 않는 방식으로 코드를 다시 작성해야 했습니다. 팀이 WebAssembly를 좋아하는 점 중 하나는 웹에서 다중 플랫폼 애플리케이션이 더 쉽게 우수한 성능을 얻을 수 있다는 것입니다. 전체 애플리케이션을 자바스크립트의 특이성에 구부릴 필요는 없습니다.

최종 결과

이러한 모든 최적화 후에 Sheets의 최종 WasmGC 버전은 계산 성능을 약 JavaScript의 두 배로 달성하여 초기 WasmGC 버전의 시작점에서 4배 개선되었음을 나타냅니다.

결론

WasmGC는 개발자가 웹 애플리케이션을 빌드하는 방식을 개선할 수 있는 강력한 기술입니다. Google에서는 향후 몇 년 동안 WasmGC가 공유 메모리 멀티스레딩을 지원하고 단일 스레드 성능을 더욱 개선할 수 있기를 기대합니다. 모든 웹 개발자는 다음 고성능 프로젝트에 WasmGC 사용을 고려해 보시기 바랍니다. 동참하여 더 빠르고 원활한 웹 환경을 만들어 보세요.

감사의 말씀

WasmGC 구현 작업에 참여해주신 분들께 감사합니다. 다이와스 아디카리, 매튜브 알브라이트, 크세니아 부키나, 줄리엔 드라믹스, 아심 파잘, 마이클 프레데릭, 고크투그 고크도건, 제니스 구, 아담 클라인, 마너스 코우크로