Fogli Google è uno dei primi prodotti di Google a utilizzare WasmGC su Chrome. Il passaggio è stato annunciato nel 2022 e i team di Fogli e Chrome hanno collaborato per la standardizzazione, l'ingegneria e gli strumenti per fornire feedback in tempo reale sulle ottimizzazioni. Questa partnership ha stabilito un precedente per il modo in cui i team tecnici di Google possono lavorare efficacemente con Chrome per avere più app Google in esecuzione su WasmGC.
La sfida: JavaScript
Il motore di calcolo di Fogli Google è stato scritto originariamente in Java e lanciato nel 2006. All'inizio, tutti i calcoli venivano eseguiti sul server. Tuttavia, dal 2013 il motore viene eseguito nel browser utilizzando JavaScript. In origine, questo veniva realizzato tramite Google Web Toolkit (GWT) e in seguito tramite il transpiler Java to Closure JavaScript (J2CL). Il motore di calcolo 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 in seguito da GWT a J2CL) è stata un'impresa importante che ha richiesto un'attenta convalida. Per garantire che il motore di calcolo JavaScript produca esattamente gli stessi risultati della versione Java, il team di Fogli ha sviluppato un meccanismo di convalida interno. Questo meccanismo può elaborare un ampio corpus di fogli e convalidare che i risultati siano identici tra più versioni del motore di calcolo. Il team di Fogli utilizza regolarmente questo strumento per convalidare le modifiche a Fogli. Il team non ha però solo confrontato i risultati di questi calcoli, ma ha anche confrontato le prestazioni tra JavaScript sul client e Java sul server. Hanno scoperto 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 con tipi flessibili. Gli ingenti investimenti in compilatori just-in-time (JIT) (ad esempio Maglev, Sparkplug e Turbofan) negli ultimi 15 anni hanno aumentato le prestazioni di JavaScript. Tuttavia, i tipi flessibili e il comportamento dinamico di JavaScript rendono difficile per i compilatori JIT generare codice ottimale. Ciò significa che JavaScript è ancora in ritardo rispetto a linguaggi come Java e C++ per la produttività non elaborata. TypeScript aggiunge la sicurezza del tipo a JavaScript, ma queste informazioni sui tipi sono progettate per semplificare lo sviluppo, non per fornire le garanzie necessarie ai compilatori per generare codice ottimale. In casi come Fogli Google, dove i calcoli di fogli di lavoro di grandi dimensioni possono richiedere decine di secondi, JavaScript è veloce, ma non abbastanza.
La soluzione: WasmGC
WasmGC è un'estensione della specifica WebAssembly esistente che aggiunge i primitivi necessari per compilare i linguaggi con raccolta dei rifiuti (come Java). Ad esempio, WasmGC aggiunge istruzioni per definire i tipi e allocare le strutture di dati con raccolta dei rifiuti. WasmGC è pronto a fare per i linguaggi con garbage collection ciò che Wasm ha fatto per C++ (ad esempio Photoshop o Google Earth), ovvero portarli sul web a una velocità quasi nativa. In Google, riteniamo che WasmGC abbia il potenziale per avere un impatto ancora maggiore di Wasm a causa della popolarità dei linguaggi con garbage collection.
Google Workspace collabora con Chrome
La bozza della specifica MVP di WasmGC è 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 vasta esperienza nella creazione e nell'ottimizzazione di compilatori e transpiler. Fogli, che fa parte di Workspace, è stato identificato come candidato ideale per la valutazione di WasmGC: è sensibile alle prestazioni e dispone di meccanismi di convalida solidi per le prestazioni e la correttezza. Chrome ha il team V8 per creare e ottimizzare il runtime WasmGC, nonché collaboratori di Binaryen per creare ottimizzazioni AOT (ahead-of-time). Chrome e Workspace offrono tutta l'esperienza necessaria per creare e ottimizzare una toolchain WasmGC, con Fogli Google come piattaforma di test ideale.
Il primo prototipo
Entro la metà del 2021, i team avevano un compilatore Java to WasmGC funzionante. Verso la fine dello stesso anno, avevano una versione prototipo di Fogli Google in esecuzione come WasmGC ed eseguivano calcoli. Lungo il percorso, ha dovuto affrontare molte sfide. Gli strumenti per la profilazione e l'acquisizione di dump dell'heap non esistevano e dovevano essere creati. L'implementazione esistente si basava su molte librerie JavaScript per le quali dovevano essere trovate o scritte sostituzioni per WasmGC. La convalida della correttezza del motore di calcolo Wasm è stata un'operazione che ha richiesto molto tempo a causa della natura sperimentale della specifica, del compilatore e delle nuove librerie. Tuttavia, i meccanismi di convalida di Fogli sono stati ancora una volta estremamente utili. Alla fine i team sono riusciti a far funzionare tutto e i dati sul rendimento hanno iniziato a essere disponibili all'inizio del 2022.
Altre ottimizzazioni
La versione iniziale di Fogli Wasm ha mostrato prestazioni di calcolo due volte più lente rispetto a JavaScript. Tuttavia, non è un cattivo risultato per una nuova specifica, un nuovo compilatore e diverse nuove librerie. Da questo punto, il team di Fogli ha iniziato l'ottimizzazione. Dalle ottimizzazioni trovate sono emerse alcune categorie:
- Replicare le ottimizzazioni di base già esistenti nella macchina virtuale Java (JVM) e in V8.
- Utilizzo di API browser altamente ottimizzate.
- Rimozione di pattern di codifica specifici di JavaScript.
Innanzitutto, il team di Fogli doveva replicare le ottimizzazioni già esistenti in altre toolchain. Il miglior esempio è l'ottimizzazione del dispatching dei metodi virtuali, che è stata a lungo ottimizzata dalla JVM e da V8, ma non esisteva nulla per WasmGC. L'implementazione dell'inlining speculativo e della devirtualizzazione, due ottimizzazioni molto comuni, ha accelerato il tempo di calcolo di circa il 40% in Chrome.
In secondo luogo, in alcuni casi le API del browser sono supportate da implementazioni native ottimizzate con cui è difficile competere utilizzando Wasm. Le stringhe e le espressioni regolari sono due buoni esempi. Nello specifico, con le espressioni regolari, il team ha registrato un aumento di quasi 100 volte della velocità delle operazioni con le espressioni regolari quando è passato da re2j (compilato in WasmGC) all'API browser RegExp
in Chrome, che può compilare ogni espressione regolare nel proprio codice macchina.
Infine, ha scoperto che anni di ottimizzazione avevano causato un adattamento eccessivo della base di codice a JavaScript. Ad esempio, avevano una struttura di dati di base in Fogli che offusca le linee di demarcazione tra array e mappe. Questo approccio è efficiente in JavaScript, che modella automaticamente gli array sparsi come mappe, ma è lento su altre piattaforme. Di conseguenza, ha dovuto riscrivere il codice in modo più indipendente dalla piattaforma. Questa è un'altra caratteristica di WebAssembly che piace al team: semplifica il raggiungimento di buone prestazioni sul web per le applicazioni multipiattaforma. Non devi adattare l'intera applicazione alle idiosincrasie di JavaScript.
Il risultato finale
Dopo tutte queste ottimizzazioni, la versione finale di WasmGC di Fogli raggiunge un rendimento di calcolo circa due volte più veloce di JavaScript, il che rappresenta un miglioramento quadruplo rispetto al punto di partenza della versione iniziale di WasmGC.
Conclusione
WasmGC è una tecnologia potente che ha il potenziale per migliorare il modo in cui gli sviluppatori creano applicazioni web. Nei prossimi anni, in Google ci auguriamo che WasmGC progredisca per supportare il multithreading con memoria condivisa e migliorare ulteriormente le prestazioni a thread singolo. 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 rendiamo insieme il web un luogo più veloce e fluido.
Ringraziamenti
Grazie a coloro che hanno lavorato all'implementazione di WasmGC e a questo caso di studio: Diwas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Asim Fazal, Michael Frederick, Goktug Gokdogan, Janice Gu, Adam Klein, Manos Koukoutos, Jakob Kummerow, Matthias Liedtke, Thomas Lively, Roberto Lublinerman, Vishrut Mehta, Thomas Nattestad, Josh Pearlstein, Joaquim Perotti, Chris Ruenes, Steven Saviano, Derek Schuff, Tim Sears, Michael Thomas, Yuan Tian, Philipp Weis, Mason Wu, Alon Zakai e Emanuel Ziegler.