Google Sheets — один из первых продуктов 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 transpiler ( J2CL ). Расчетный движок JavaScript работает в Web Worker и взаимодействует с основным потоком с помощью MessageChannel
.
Миграция пользователей с сервера на версию JavaScript вычислительного движка (а позднее с GWT на J2CL) была серьезным начинанием, требовавшим тщательной проверки. Чтобы гарантировать, что вычислительный движок JavaScript выдает точно такие же результаты, как и версия Java, команда Sheets разработала внутренний механизм проверки. Этот механизм может обрабатывать большой корпус таблиц и проверять идентичность результатов между несколькими версиями вычислительного движка. Команда Sheets регулярно использует этот инструмент для проверки изменений в Sheets. Но команда не просто сравнивала результаты этих вычислений, она также сравнивала производительность между JavaScript на клиенте и Java на сервере. Они обнаружили, что версия JavaScript вычислительного движка была более чем в три раза медленнее, чем версия Java.
Почему JavaScript медленнее Java?
JavaScript быстр для слаботипизированного, динамического языка. Значительные инвестиции в компиляторы just-in-time (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 для создания оптимизаций ahead-of-time (AOT). У Chrome и Workspace есть все необходимые знания для создания и оптимизации цепочки инструментов WasmGC, а Google Sheets является идеальным испытательным стендом.
Первый прототип
К середине 2021 года у команд был работающий компилятор Java в WasmGC . К концу того же года у них была прототипная версия Google Таблиц, работающая как WasmGC и выполняющая вычисления. По пути они столкнулись со многими проблемами. Инструментов для профилирования и создания дампов кучи не существовало, и их нужно было создать. Существующая реализация опиралась на множество библиотек JavaScript, для которых нужно было найти или написать замены для WasmGC. Проверка правильности вычислительного движка Wasm была трудоемкой работой из-за экспериментального характера спецификации, компилятора и новых библиотек. Но механизмы проверки Таблиц снова оказались чрезвычайно полезными. В конечном итоге команды заставили все это работать, и данные о производительности начали поступать в начале 2022 года.
Дополнительные оптимизации
Первоначальная версия Sheets Wasm показала производительность вычислений примерно в два раза медленнее, чем JavaScript. Однако это неплохой результат для новой спецификации, нового компилятора и нескольких новых библиотек. С этого момента команда Sheets начала оптимизацию. Из найденных ими оптимизаций выделилось несколько категорий:
- Повторение основных оптимизаций, которые уже существовали в виртуальной машине Java (JVM) и в V8.
- Использование высокооптимизированных API браузеров.
- Удаление шаблонов кодирования, специфичных для JavaScript.
Во-первых, команде Sheets нужно было повторить оптимизации, которые уже существуют в других инструментальных цепочках. Лучшим примером этого является оптимизация диспетчеризации виртуальных методов , которая давно оптимизирована JVM и V8, но для WasmGC ничего не существовало. Реализация спекулятивного встраивания и девиртуализации — двух очень распространенных оптимизаций — ускорила время вычислений примерно на 40% в Chrome.
Во-вторых, есть случаи, когда API браузера поддерживаются оптимизированными собственными реализациями, с которыми трудно конкурировать с использованием Wasm. Строки и регулярные выражения — два хороших примера. В частности, с регулярными выражениями команда увидела почти 100-кратное ускорение операций с регулярными выражениями при переходе с re2j (скомпилированного в WasmGC) на API браузера RegExp
в Chrome, который может компилировать каждое регулярное выражение в свой собственный машинный код.
Наконец, они обнаружили, что годы оптимизации привели к тому, что кодовая база была слишком подогнана под JavaScript. Например, у них была основная структура данных в Таблицах, которая стирала границы между массивами и картами. Это эффективно в JavaScript, который автоматически моделирует разреженные массивы как карты, но медленно на других платформах. Поэтому им пришлось переписать код более платформенно-независимым способом. Это еще одна вещь, которая нравится команде в WebAssembly: он упрощает для многоплатформенных приложений достижение хорошей производительности в Интернете. Вам не нужно подгонять все свое приложение под особенности JavaScript.
Окончательный результат
После всех этих оптимизаций окончательная версия Sheets WasmGC достигает производительности вычислений примерно в два раза выше, чем у JavaScript , что представляет собой четырехкратное улучшение по сравнению с начальной точкой первоначальной версии WasmGC.
Заключение
WasmGC — это мощная технология, которая может улучшить способ, которым разработчики создают веб-приложения. В ближайшие годы в Google мы надеемся увидеть, как WasmGC будет поддерживать многопоточность общей памяти и еще больше улучшит производительность однопоточных приложений. Мы призываем всех веб-разработчиков рассмотреть возможность использования WasmGC для своего следующего высокопроизводительного проекта. Присоединяйтесь к нам и вместе сделайте Интернет более быстрым и плавным!
Благодарности
Спасибо всем, кто работал над реализацией WasmGC и этим практическим примером: Дивас Адхикари, Мэтью Олбрайт, Ксения Букина, Жюльен Драме, Асим Фазал, Майкл Фредерик, Гоктуг Гокдоган, Дженис Гу, Адам Кляйн, Манос Кукутос, Якоб Куммеров, Маттиас Лидтке, Томас Лайвли, Роберто Люблинерман, Вишрут Мехта, Томас Наттестад, Джош Перлштейн, Хоаким Перотти, Крис Руэнес, Стивен Савиано, Дерек Шуфф, Тим Сирс, Майкл Томас, Юань Тянь, Филипп Вайс, Мейсон Ву, Алон Закаи и Эмануэль Циглер.