Hojas de cálculo de Google es uno de los primeros productos de Google en usar WasmGC en Chrome. El cambio se anunció en 2022, y los equipos de Hojas de cálculo y Chrome se asociaron en la estandarización, la ingeniería y las herramientas para proporcionar comentarios en tiempo real sobre las optimizaciones. Esta asociación estableció un precedente para que los equipos de ingeniería de Google puedan trabajar de manera eficaz con Chrome para que más apps de Google se ejecuten en WasmGC.
El desafío: JavaScript
El motor de cálculo de Hojas de cálculo de Google se escribió originalmente en Java y se lanzó en 2006. En los primeros días del producto, todos los cálculos se realizaban en el servidor. Sin embargo, desde 2013, el motor se ejecuta en el navegador con JavaScript. Esto se logró originalmente a través de Google Web Toolkit (GWT) y, más tarde, a través del transpilador de Java a JavaScript de Closure (J2CL). El motor de cálculo de JavaScript se ejecuta en un trabajador web y se comunica con el subproceso principal a través de un MessageChannel
.
Migrar a los usuarios del servidor a la versión de JavaScript del motor de cálculo (y, más tarde, de GWT a J2CL) fue una tarea importante que requirió una validación cuidadosa. Para garantizar que el motor de cálculo de JavaScript produjera exactamente los mismos resultados que la versión de Java, el equipo de Hojas de cálculo desarrolló un mecanismo de validación interno. Este mecanismo puede procesar un gran corpus de hojas y validar que los resultados sean idénticos entre varias versiones del motor de cálculo. El equipo de Hojas de cálculo usa esta herramienta con frecuencia para validar los cambios en Hojas de cálculo. Sin embargo, el equipo no solo comparó los resultados de esos cálculos, sino que también comparó el rendimiento entre JavaScript en el cliente y Java en el servidor. Descubrieron que la versión de JavaScript del motor de cálculo era más de tres veces más lenta que la versión de Java.
¿Por qué JavaScript es más lento que Java?
JavaScript es rápido para un lenguaje dinámico y de tipado flexible. La gran inversión en compiladores justo a tiempo (JIT) (por ejemplo, Maglev, Sparkplug y Turbofan) durante los últimos 15 años aumentó el rendimiento de JavaScript. Sin embargo, los tipos flexibles y el comportamiento dinámico de JavaScript dificultan que los compiladores JIT generen un código óptimo. Esto significa que JavaScript aún se encuentra por detrás de lenguajes como Java y C++ en cuanto a la capacidad de procesamiento sin procesar. TypeScript agrega seguridad de tipos a JavaScript, pero esa información de tipo está diseñada para facilitar el desarrollo, no para proporcionar el tipo de garantías que necesitan los compiladores para generar un código óptimo. En casos como Hojas de cálculo de Google, en los que las hojas de cálculo grandes pueden tardar decenas de segundos en calcularse, JavaScript es rápido, pero no lo suficientemente rápido.
La solución: WasmGC
WasmGC es una extensión de la especificación existente de WebAssembly que agrega las primitivas necesarias para compilar lenguajes con recolección de basura (como Java). Por ejemplo, WasmGC agrega instrucciones para definir tipos y asignar estructuras de datos con recolección de basura. WasmGC está listo para hacer para los lenguajes con recolección de basura lo que Wasm hizo para C++ (por ejemplo, Photoshop o Google Earth), que es llevarlos a la Web a una velocidad casi nativa. En Google, creemos que WasmGC tiene el potencial de tener un impacto aún mayor que Wasm debido a la popularidad de los lenguajes con recolección de basura.
Google Workspace se asocia con Chrome
El borrador de la especificación de MVP de WasmGC se publicó en 2019. A fines de 2020, Google Workspace y Chrome se asociaron para evaluar WasmGC con el motor de cálculo de Hojas de cálculo. El equipo multiplataforma de Workspace tiene una amplia experiencia en la compilación y optimización de compiladores y transpiladores. Hojas de cálculo, que forma parte de Workspace, se identificó como un candidato ideal para evaluar WasmGC: es sensible al rendimiento y tiene mecanismos sólidos de validación de rendimiento y corrección. Chrome tiene el equipo de V8 para compilar y optimizar el entorno de ejecución de WasmGC, así como colaboradores de Binaryen para compilar optimizaciones por adelantado (AOT). Entre Chrome y Workspace, tienes toda la experiencia necesaria para compilar y optimizar una cadena de herramientas de WasmGC, con Hojas de cálculo de Google como un entorno de prueba ideal.
El primer prototipo
A mediados de 2021, los equipos tenían un compilador de Java a WasmGC en funcionamiento. A fines del mismo año, tenían una versión prototipo de Hojas de cálculo de Google que se ejecutaba como WasmGC y realizaba cálculos. En el camino, se encontraron con muchos desafíos. Las herramientas para generar perfiles y tomar volcados de montón no existían y debían compilarse. La implementación existente se basaba en muchas bibliotecas de JavaScript para las que se debían encontrar reemplazos o escribirlos para WasmGC. Validar la exactitud del motor de cálculo de Wasm fue un esfuerzo que requirió mucho tiempo debido a la naturaleza experimental de la especificación, el compilador y las bibliotecas nuevas. Pero los mecanismos de validación de Hojas de cálculo volvieron a ser de gran ayuda. Finalmente, los equipos lograron que todo funcionara, y los datos de rendimiento comenzaron a llegar a principios de 2022.
Optimizaciones adicionales
La versión inicial de Hojas de cálculo Wasm mostró un rendimiento de cálculo aproximadamente dos veces más lento que JavaScript. Sin embargo, este no es un mal resultado para una especificación, un compilador y varias bibliotecas nuevas. A partir de ese momento, el equipo de Hojas de cálculo comenzó a realizar optimizaciones. De las optimizaciones que encontró, surgieron algunas categorías:
- Replicar las optimizaciones principales que ya existían en la máquina virtual de Java (JVM) y en V8
- Usar APIs de navegador altamente optimizadas
- Se quitaron los patrones de codificación específicos de JavaScript.
En primer lugar, el equipo de Hojas de cálculo necesitaba replicar las optimizaciones que ya existen en otras cadenas de herramientas. El mejor ejemplo de esto es la optimización del envío de métodos virtuales, que la JVM y V8 llevan mucho tiempo optimizando, pero no existía nada para WasmGC. La implementación de la alineación especulativa y la desvirtualización, dos optimizaciones muy comunes, aceleró el tiempo de cálculo en aproximadamente un 40% en Chrome.
En segundo lugar, hay casos en los que las APIs del navegador están respaldadas por implementaciones nativas optimizadas con las que es difícil competir con Wasm. Las cadenas y las expresiones regulares son dos buenos ejemplos. Específicamente, con las expresiones regulares, el equipo observó una aceleración de casi 100 veces en las operaciones de expresiones regulares cuando se cambió de re2j (compilada en WasmGC) a la API del navegador RegExp
en Chrome, que puede compilar cada expresión regular en su propio código máquina.
Por último, descubrió que años de optimización habían provocado que la base de código estuviera sobreajustada a JavaScript. Por ejemplo, tenían una estructura de datos principal en Hojas de cálculo que difuminaba las líneas entre los arrays y los mapas. Esto es eficiente en JavaScript, que modela automáticamente arrays dispersos como mapas, pero es lento en otras plataformas. Por lo tanto, tuvieron que reescribir el código de una manera más independiente de la plataforma. Esta es otra característica que al equipo le gusta de WebAssembly: facilita que las aplicaciones multiplataforma obtengan un buen rendimiento en la Web. No tienes que adaptar toda tu aplicación a las idiosincrasias de JavaScript.
El resultado final
Después de todas estas optimizaciones, la versión final de WasmGC de Hojas de cálculo logra un rendimiento de cálculo aproximadamente el doble de rápido que JavaScript, lo que representa una mejora cuatro veces mayor desde el punto inicial de la versión inicial de WasmGC.
Conclusión
WasmGC es una tecnología potente que tiene el potencial de mejorar la forma en que los desarrolladores compilan aplicaciones web. En los próximos años, en Google, esperamos que WasmGC avance para admitir multithreading de memoria compartida y mejorar aún más el rendimiento de un solo subproceso. Recomendamos a todos los desarrolladores web que consideren usar WasmGC para su próximo proyecto de alto rendimiento. Únete a nosotros y hagamos juntos que la Web sea un lugar más rápido y fluido.
Agradecimientos
Gracias a quienes trabajaron en la implementación de WasmGC y en este caso de éxito: 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 y Emanuel Ziegler.