Perché Fogli Google ha trasferito il suo worker di calcolo da JavaScript a WasmGC

Fogli Google è uno dei primi prodotti Google a utilizzare WasmGC su Chrome. Il trasferimento è stato annunciato nel 2022 e i team di Fogli e Chrome hanno collaborato per standardizzazione, progettazione e strumenti per fornire feedback in tempo reale sulle ottimizzazioni. Questa partnership ha dato vita a un precedente modo in cui i team tecnici di Google possono collaborare in modo efficace con Chrome per far funzionare più app Google su WasmGC.

La sfida: JavaScript

Il motore di calcolo di Fogli Google è stato originariamente scritto in Java e lanciato nel 2006. All'inizio, tutti i calcoli avveniva sul server. Tuttavia, dal 2013 il motore è stato eseguito nel browser utilizzando JavaScript. Questa operazione è stata eseguita in origine tramite Google Web Toolkit (GWT) e successivamente tramite il transpiler Java to Closure JavaScript (J2CL). Il motore di calcolo di JavaScript viene eseguito in un web worker e comunica con il thread principale utilizzando un MessageChannel.

La migrazione degli utenti dal server alla versione JavaScript del motore di calcolo (e successivamente da GWT a J2CL) è stata un'impresa importante che ha richiesto un'attenta convalida. Per garantire che il motore di calcolo JavaScript generasse esattamente gli stessi risultati della versione Java, il team di Fogli ha sviluppato un meccanismo di convalida interna. Questo meccanismo può elaborare un grande corpus di fogli e confermare che i risultati siano identici tra più versioni del motore di calcolo. Il team di Fogli utilizza regolarmente questo strumento per convalidare le modifiche apportate a Fogli. Tuttavia, il team non ha semplicemente confrontato i risultati di questi calcoli, ma ha anche confrontato le prestazioni tra JavaScript sul client e Java sul server. È emerso che la versione JavaScript del motore di calcolo era più di tre volte più lenta della versione Java.

Perché JavaScript è più lento di Java?

JavaScript è veloce per un linguaggio dinamico e a caratteri generici. Gli investimenti importanti nei compilatori just-in-time (JIT) (ad esempio, Maglev, Sparkplug e Turbofan) negli ultimi 15 anni hanno aumentato le prestazioni di JavaScript. Tuttavia, i tipi liberi e il comportamento dinamico di JavaScript rendono difficile per i compilatori JIT generare un codice ottimale. Ciò significa che JavaScript è ancora in ritardo rispetto a linguaggi come Java e C++ per la velocità effettiva non elaborata. TypeScript aggiunge la sicurezza dei tipi a JavaScript, ma queste informazioni sul tipo sono progettate per semplificare lo sviluppo, non per fornire i tipi di garanzie necessarie dai compilatori per generare un codice ottimale. Per casi come Fogli Google, in cui il calcolo di fogli di lavoro di grandi dimensioni può richiedere decine di secondi, JavaScript è veloce, ma non abbastanza veloce.

La soluzione: WasmGC

WasmGC è un'estensione alla specifica WebAssembly esistente che aggiunge le primitive necessarie per compilare i linguaggi di garbage collection (come Java). Ad esempio, WasmGC aggiunge istruzioni per definire i tipi e allocare le strutture dei dati di garbage collection. WasmGC è destinato a fare per le lingue di garbage collection ciò che ha fatto per C++ (ad esempio, Photoshop o Google Earth), in modo da portarle sul web quasi alla velocità nativa. Noi di Google crediamo che WasmGC abbia il potenziale per essere ancora più incisivo di Wasm a causa della popolarità delle lingue per la raccolta dei rifiuti.

Google Workspace collabora con Chrome

La bozza di specifica WasmGC MVP è stata pubblicata nel 2019. Alla fine del 2020, Google Workspace e Chrome hanno collaborato per valutare WasmGC utilizzando il motore di calcolo di Fogli. Il team multipiattaforma di Workspace ha una grande esperienza nello sviluppo e nell'ottimizzazione di compilatori e transpiler. Fogli, che fa parte di Workspace, è stato identificato come il candidato ideale per la valutazione di WasmGC: è sensibile alle prestazioni e dispone di solidi meccanismi di convalida delle prestazioni e della correttezza. Chrome ha il team V8 per creare e ottimizzare il runtime WasmGC, nonché collaboratori a Binaryen per creare ottimizzazioni in anticipo (AOT). Tra Chrome e Workspace, c'è tutta l'esperienza necessaria per creare e ottimizzare una catena di strumenti WasmGC, con Fogli Google come banco di prova ideale.

Il primo prototipo

Entro la metà del 2021, i team avevano un compilatore da Java a WasmGC funzionante. Verso la fine dello stesso anno, l'azienda disponeva di una versione prototipo di Fogli Google in esecuzione come WasmGC ed esegue i calcoli. Durante il loro percorso, hanno dovuto affrontare molte sfide. Non esistevano strumenti per la profilazione e l'esecuzione dei dump dell'heap e dovevano essere creati. L'implementazione esistente si basava su molte librerie JavaScript per le quali era necessario trovare o scrivere sostituzioni per WasmGC. La convalida della correttezza del motore di calcolo Wasm ha richiesto molto tempo a causa della natura sperimentale della specifica, del compilatore e delle nuove librerie. Ma i meccanismi di convalida di Fogli sono stati ancora una volta estremamente utili. Alla fine i team hanno risolto il problema e i dati sul rendimento hanno iniziato ad arrivare all'inizio del 2022.

Ottimizzazioni aggiuntive

La versione iniziale di Wasm in Fogli mostrava un rendimento del calcolo circa due volte più lento rispetto a JavaScript. Tuttavia, questo non è un cattivo risultato per una nuova specifica, un nuovo compilatore e diverse nuove librerie. A questo punto, il team di Fogli ha iniziato l'ottimizzazione. Tra le ottimizzazioni individuate, sono emerse alcune categorie:

  • Replica delle ottimizzazioni principali già esistenti nella Java Virtual Machine (JVM) e nella V8.
  • Utilizzo di API browser altamente ottimizzate.
  • Rimozione dei pattern di programmazione specifici di JavaScript.

In primo luogo, il team di Fogli doveva replicare le ottimizzazioni che già esistono in altre toolchain. L'esempio migliore è l'ottimizzazione del deployment di metodi virtuali, che è stato a lungo ottimizzato da JVM e V8, ma non esisteva nulla per WasmGC. L'implementazione dell'incorporamento speculativo e della devirtualizzazione, due ottimizzazioni molto comuni, ha accelerato i tempi di calcolo di circa il 40% in Chrome.

In secondo luogo, ci sono casi in cui le API del browser sono supportate da implementazioni native ottimizzate con cui è difficile competere con Wasm. Stringhe ed espressioni regolari sono due buoni esempi. Nello specifico, con le espressioni regolari, il team ha registrato un'accelerazione quasi 100 volte superiore delle operazioni di espressione regolare passando da re2j (compilato in WasmGC) all'API browser RegExp in Chrome, che può compilare ogni espressione regolare nel proprio codice macchina.

Infine, hanno scoperto che anni di ottimizzazione avevano causato un adattamento del codebase a JavaScript. Ad esempio, avevano una struttura di dati di base in Fogli che sfocava le linee tra array e mappe. Questo è efficiente in JavaScript, che modella automaticamente array sparsi come mappe, ma è lento su altre piattaforme. Ha quindi dovuto riscrivere il codice in modo più indipendente dalla piattaforma. Questa è un'altra cosa che il team apprezza di WebAssembly: consente alle applicazioni multipiattaforma di ottenere più facilmente buone prestazioni sul web. Non è necessario piegare l'intera applicazione alle idiosincrasie di JavaScript.

Il risultato finale

Dopo tutte queste ottimizzazioni, la versione finale WasmGC di Fogli raggiunge un rendimento di calcolo due volte più veloce di JavaScript, il che rappresenta un miglioramento di quattro volte rispetto al punto iniziale della versione WasmGC iniziale.

Conclusione

WasmGC è una potente tecnologia che ha il potenziale per migliorare il modo in cui gli sviluppatori creano applicazioni web. Nei prossimi anni, in Google ci auguriamo di vedere avanzare WasmGC per supportare il multithreading della memoria condivisa e migliorare ulteriormente le prestazioni dei singoli thread. Invitiamo tutti gli sviluppatori web a prendere in considerazione l'utilizzo di WasmGC per il loro prossimo progetto ad alte prestazioni. Unisciti a noi e rendi il web un luogo più veloce e fluido insieme.

Ringraziamenti

Grazie a chi ha lavorato all'implementazione di WasmGC e a questo case study: Diwas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Asim Fazal, Michael Frederick, Goktug Gokdogan, Janice Gu, Adam Klein, Manos Koukoutos