Почему Google Таблицы перенесли свой вычислительный инструмент с JavaScript на WasmGC

Google Таблицы — один из первых продуктов Google, использующих WasmGC в Chrome. Об этом шаге было объявлено в 2022 году, и команды Sheets и Chrome начали сотрудничать в области стандартизации, проектирования и инструментов, чтобы предоставлять обратную связь по оптимизации в режиме реального времени. Это партнерство создало прецедент того, как инженерные группы Google могут эффективно работать с Chrome, чтобы больше приложений Google работало на WasmGC.

Задача: JavaScript

Механизм вычислений Google Sheets изначально был написан на Java и запущен в 2006 году. На заре существования продукта все вычисления выполнялись на сервере. Однако с 2013 года движок работает в браузере с использованием JavaScript. Первоначально это было достигнуто с помощью Google Web Toolkit ( GWT ), а затем с помощью транспилятора Java to Closure JavaScript ( J2CL ). Механизм вычислений JavaScript работает в Web Worker и взаимодействует с основным потоком с помощью MessageChannel .

Миграция пользователей с сервера на версию вычислительной машины JavaScript (а позже с GWT на J2CL) была серьезной задачей, требовавшей тщательной проверки. Чтобы гарантировать, что механизм вычислений JavaScript дает точно такие же результаты, что и версия Java, команда Sheets разработала внутренний механизм проверки. Этот механизм может обрабатывать большой массив листов и проверять идентичность результатов в нескольких версиях механизма вычислений. Команда Таблиц регулярно использует этот инструмент для проверки изменений в Таблицах. Но команда не просто сравнила результаты этих вычислений, они также сравнили производительность JavaScript на клиенте и Java на сервере. Они обнаружили, что версия вычислительной машины на JavaScript более чем в три раза медленнее, чем версия на Java.

Почему JavaScript медленнее Java?

JavaScript работает быстро для свободно типизированного динамического языка. Крупные инвестиции в JIT-компиляторы (например, Maglev , Sparkplug и Turbofan ) за последние 15 лет увеличили производительность JavaScript. Однако свободные типы и динамическое поведение JavaScript затрудняют создание оптимального кода JIT-компиляторами. Это означает, что JavaScript по-прежнему отстает от таких языков, как Java и C++, по производительности. TypeScript добавляет безопасность типов в JavaScript, но эта информация о типах предназначена для облегчения разработки, а не для предоставления каких-то гарантий, необходимых компиляторам для генерации оптимального кода. В таких случаях, как Google Sheets, где расчет больших таблиц может занять десятки секунд, JavaScript работает быстро, но недостаточно быстро.

Решение: WasmGC

WasmGC — это расширение существующей спецификации WebAssembly , которое добавляет примитивы, необходимые для компиляции языков со сборкой мусора (таких как Java). Например, WasmGC добавляет инструкции для определения типов и выделения структур данных, собираемых мусором. WasmGC готов сделать для языков со сборкой мусора то же, что Wasm сделал для C++ (например, Photoshop или Google Earth ), то есть перенести их в Интернет со скоростью, близкой к естественной. В Google мы считаем, что WasmGC может оказаться даже более эффективным, чем Wasm, из-за популярности языков со сборщиком мусора.

Google Workspace сотрудничает с Chrome

Черновой вариант спецификации WasmGC MVP был опубликован в 2019 году. В конце 2020 года Google Workspace и Chrome объединились для оценки WasmGC с использованием вычислительной системы Sheets. Мультиплатформенная команда Workspace обладает значительным опытом создания и оптимизации компиляторов и транспиляторов. Sheets, часть Workspace, была признана идеальным кандидатом для оценки WasmGC: она чувствительна к производительности и имеет надежные механизмы проверки производительности и правильности. У Chrome есть команда V8 для создания и оптимизации среды выполнения WasmGC, а также участники Binaryen для создания предварительной оптимизации (AOT). Chrome и Workspace обладают всем необходимым опытом для создания и оптимизации цепочки инструментов WasmGC, а Google Sheets — идеальным испытательным стендом.

Первый прототип

К середине 2021 года у команд был работающий компилятор Java для WasmGC . К концу того же года у них появился прототип версии Google Sheets, работающий под именем WasmGC и выполняющий вычисления. По пути они столкнулись со многими проблемами. Инструментов для профилирования и получения дампов кучи не существовало, и их нужно было создать. Существующая реализация опиралась на множество библиотек JavaScript, которым нужно было найти замену или написать для WasmGC. Проверка правильности вычислительного механизма Wasm заняла много времени из-за экспериментального характера спецификации, компилятора и новых библиотек. Но механизмы проверки Sheets снова оказались чрезвычайно полезными. В конечном итоге команды заработали, и данные о производительности начали поступать в начале 2022 года.

Дополнительные оптимизации

Первоначальная версия Sheets Wasm показала производительность вычислений примерно в два раза медленнее , чем JavaScript. Однако это неплохой результат для новой спецификации, нового компилятора и нескольких новых библиотек. С этого момента команда Sheets начала оптимизацию. Из найденных ими оптимизаций выделилось несколько категорий:

  • Репликация основных оптимизаций, которые уже существовали в виртуальной машине Java (JVM) и в V8.
  • Использование высокооптимизированных API браузера.
  • Удаление шаблонов кодирования, специфичных для JavaScript.

Во-первых, команде Sheets необходимо было воспроизвести оптимизации, которые уже существуют в других цепочках инструментов. Лучшим примером этого является оптимизация диспетчеризации виртуальных методов , которая уже давно оптимизирована для JVM и V8, но для WasmGC ничего не существовало. Реализация спекулятивной встраивания и девиртуализации — двух очень распространенных оптимизаций — ускорила время вычислений в Chrome примерно на 40%.

Во-вторых, бывают случаи, когда API браузера поддерживаются оптимизированными собственными реализациями, с которыми трудно конкурировать при использовании Wasm. Строки и регулярные выражения — два хороших примера. В частности, что касается регулярных выражений, команда заметила почти 100-кратное ускорение операций с регулярными выражениями при переходе от re2j (скомпилированного в WasmGC) к API браузера RegExp в Chrome, который может компилировать каждое регулярное выражение в свой собственный машинный код.

Наконец, они обнаружили, что годы оптимизации привели к тому, что кодовая база была перенастроена на JavaScript. Например, у них была базовая структура данных в Таблицах, которая стирала границы между массивами и картами. Это эффективно в JavaScript, который автоматически моделирует разреженные массивы как карты, но медленно на других платформах. Поэтому им пришлось переписать код, сделав его более независимым от платформы. Это еще одна вещь, которая нравится команде в WebAssembly: с ее помощью многоплатформенным приложениям легче добиться хорошей производительности в Интернете. Вам не обязательно подстраивать все свое приложение под особенности JavaScript.

Окончательный результат

После всех этих оптимизаций окончательная версия Sheets для WasmGC обеспечивает производительность вычислений примерно в два раза выше, чем в JavaScript , что представляет собой четырехкратное улучшение по сравнению с исходной версией WasmGC.

Заключение

WasmGC — это мощная технология, которая может улучшить способы создания веб-приложений разработчиками. В ближайшие годы мы в Google надеемся увидеть, как WasmGC будет поддерживать многопоточность с общей памятью и еще больше улучшит однопоточную производительность. Мы призываем всех веб-разработчиков рассмотреть возможность использования WasmGC для своего следующего высокопроизводительного проекта. Присоединяйтесь к нам и вместе сделайте Интернет быстрее и удобнее!

Благодарности

Спасибо тем, кто работал над реализацией WasmGC и этим практическим примером: Дивас Адикари, Мэтью Олбрайт, Ксения Букина, Жюльен Драма, Асим Фазал, Майкл Фредерик, Гоктуг Гокдоган, Дженис Гу, Адам Кляйн, Манос Кукутос, Якоб Куммеров, Маттиас Лидтке. , Томас Лайвли, Роберто Люблинерман, Вишрут Мехта, Томас Наттестад, Джош Перлштейн, Хоаким Перотти, Крис Рюнес, Стивен Савиано, Дерек Шафф, Тим Сирс, Майкл Томас, Юань Тиан, Филипп Вайс, Мейсон Ву, Алон Закай и Эмануэль Зиглер.