Por qué Hojas de cálculo de Google transfirió su trabajador de cálculo de JavaScript a WasmGC

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 para trabajar con estandarización, ingeniería y herramientas para proporcionar comentarios en tiempo real sobre las optimizaciones. Esta asociación sentó un precedente para la manera en que los equipos de ingeniería de Google pueden trabajar eficazmente con Chrome para tener más apps de Google ejecutándose 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, todo el cálculo se llevaba a cabo en el servidor. Sin embargo, desde 2013, el motor se ejecutó en el navegador mediante JavaScript. Originalmente, esto se logró a través de Google Web Toolkit (GWT) y, luego, a través de Java al transpilador de JavaScript de cierre (J2CL). El motor de cálculo de JavaScript se ejecuta en un Web Worker y se comunica con el subproceso principal mediante un MessageChannel.

Migrar los usuarios del servidor a la versión de JavaScript del motor de cálculo (y, luego, de GWT a J2CL) fue una tarea importante que requería una validación cuidadosa. Para garantizar que el motor de cálculo de JavaScript produzca 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 múltiples versiones del motor de cálculo. El equipo de Hojas de cálculo usa esta herramienta con regularidad para validar los cambios que se realizan 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 tipos flexibles. La inversión considerable 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 individuales y el comportamiento dinámico de JavaScript dificultan que los compiladores de JIT generen un código óptimo. Esto significa que JavaScript todavía está rezagado con respecto a lenguajes como Java y C++ en lo que respecta 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 código óptimo. En casos como Hojas de cálculo de Google, donde 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 a la especificación existente WebAssembly que agrega las primitivas necesarias para compilar lenguajes no utilizados (como Java). Por ejemplo, WasmGC agrega instrucciones para definir los tipos y asignar estructuras de datos de recolección de elementos no utilizados. WasmGC está preparado para realizar en el caso de los lenguajes de recolección de elementos no utilizados, lo que hizo Wasm en C++ (por ejemplo, Photoshop o Google Earth), y llevarlos a la Web a una velocidad casi nativa. En Google, creemos que WasmGC tiene el potencial de ser aún más impactante que Wasm debido a la popularidad de estos lenguajes.

Google Workspace se asocia con Chrome

La especificación del borrador del 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 cuenta con una gran 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, ya que tiene en cuenta el rendimiento y cuenta con mecanismos de validación sólidos de rendimiento y precisión. Chrome tiene el equipo de V8 para crear y optimizar el entorno de ejecución WasmGC, así como colaboradores de Binaryen para crear optimizaciones anticipadas (AOT). Entre Chrome y Workspace, existe toda la experiencia necesaria para crear y optimizar una cadena de herramientas de WasmGC con Hojas de cálculo de Google como un banco de pruebas ideal.

El primer prototipo

Para mediados de 2021, los equipos contaban con un compilador de Java a WasmGC en funcionamiento. Hacia fines de ese mismo año, tenían una versión de prototipo de Hojas de cálculo de Google que se ejecutaba como WasmGC y que 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 dependía de muchas bibliotecas de JavaScript para las cuales era necesario encontrar o escribir reemplazos para WasmGC. Validar la precisión del motor de cálculo de Wasm requería 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 resultaron de nuevo muy útiles. Finalmente, los equipos lograron que todo funcionara, y los datos de rendimiento comenzaron a estar disponibles a principios de 2022.

Optimizaciones adicionales

En la versión inicial de Hojas de cálculo de Wasm, el rendimiento del cálculo era aproximadamente dos veces más lento que el de JavaScript. Sin embargo, este no es un mal resultado para una nueva especificación, un nuevo compilador y varias bibliotecas nuevas. A partir de este momento, el equipo de Hojas de cálculo comenzó a realizar optimizaciones. De las optimizaciones que encontraron, surgieron algunas categorías:

  • Replicar las optimizaciones principales que ya existían en la máquina virtual Java (JVM) y en V8.
  • Uso de APIs de navegador altamente optimizadas
  • Quita los patrones de programación específicos de JavaScript.

En primer lugar, el equipo de Hojas de cálculo debía 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 optimizaron desde hace mucho tiempo, pero no existía nada para WasmGC. La implementación del interlineado especulativo y la desvirtualización (dos optimizaciones muy comunes) aceleró el tiempo de cálculo en casi un 40% en Chrome.

En segundo lugar, hay casos en los que las APIs del navegador están respaldadas por implementaciones nativas optimizadas que son difíciles de competir con el uso de Wasm. Las cadenas y las expresiones regulares son dos buenos ejemplos. Específicamente, con las expresiones regulares, el equipo notó que las operaciones de expresión regular se aceleraron casi 100 veces al cambiar de re2j (compilado a 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, descubrieron que los años de optimización habían provocado que la base de código se sobreajustara a JavaScript. Por ejemplo, tenían una estructura de datos central en Hojas de cálculo que desdibujaba las líneas entre arrays y mapas. Esto es eficiente en JavaScript, que modela automáticamente arrays dispersos como mapas, pero es lento en otras plataformas. Por lo tanto, debieron volver a escribir el código de una manera más independiente de la plataforma. Esto es otra cosa que al equipo le gusta de WebAssembly: facilita que las aplicaciones multiplataforma tengan un buen rendimiento en la Web. No es necesario que modifiques toda tu aplicación a las idiosincrasias de JavaScript.

El resultado final

Después de todas estas optimizaciones, la versión final de WasmGC en Hojas de cálculo logra un rendimiento de cálculo de aproximadamente dos veces más rápido que JavaScript, lo que representa una mejora cuádruple desde el punto de partida de la versión inicial de WasmGC.

Conclusión

WasmGC es una tecnología potente que tiene el potencial de avanzar en la forma en que los desarrolladores crean aplicaciones web. En los próximos años, esperamos ver el avance de WasmGC para admitir varios subprocesos de memoria compartida y mejorar aún más el rendimiento de subprocesos únicos. Recomendamos a todos los desarrolladores web que consideren usar WasmGC en su próximo proyecto de alto rendimiento. Únete a nosotros y haz de la Web un lugar más rápido y fluido en conjunto.

Agradecimientos

Gracias por los que 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, Jowas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Asim Fazal, Michael Frederick, Goktug Gokdogan, Janice Gu,