BREAKING CHANGE: переписать утилиты на Rust / C# с интеграцией через Wasm
scffs opened this issue · comments
В чём суть
- Утилита (функция), написанная на расте, будет работать в разы быстрее того же JS
- Через WebAssembly идет конвертирование кода на Rust в бинарник, который потом запускается в виртуальной машине в браузере.
- Для доп. перфоманса можно вынести в воркер, но не думаю, что есть нужда
Тут могут быть подводные камни в виде:
- Слишком мелкая разница. В итоге мы зря потратим время
- Станет хуже. У нас появляется прослойка в виде JS -> Wasm -> Binary code -> чистый результат отдается обратно в JS, что может ухудшить перфоманс
anyway это хороший опыт, т.к. Wasm используется во многих крупных проектах (например, Figma), а связывать Rust с Preact очень даже весело :)
Как это работает:
Пример переписанной утилиты:
ВАЖНО! Эта утилита мега простая и её 100% можно оставить на чистом JS, но для примера перепишем на Rust.
import init, * as wasm from '../../pkg'
export const isToday = async (date: Date): Promise<boolean> => {
await init()
const day = date.getDate()
const month = date.getMonth()
const year = date.getFullYear()
return wasm.is_today(day, month, year)
}
pub fn is_today(day: u32, month: u32, year: u32) -> bool {
let today = js_sys::Date::new_0();
let today_day = today.get_date();
let today_month = today.get_month();
let today_year = today.get_full_year();
today_day == day && today_month == month && today_year == year
}
Когда JavaScript вызывает isToday
, он инициализирует WebAssembly модуль (используя await init()
), чтобы загрузить функции Rust в память.
isToday
извлекает день, месяц и год из объекта Date в JavaScript.
Эти значения передаются в функцию is_today
в Rust, которая сравнивает переданную дату с текущей датой, используя JavaScript Date.
Результат этого сравнения возвращается в JavaScript.
Что внутри Wasm
Интерпретация и компиляция
-
Интерпретация: Браузер загружает и интерпретирует бинарный код Wasm с помощью встроенной виртуальной машины.
-
Компиляция Just-in-Time (JIT): Браузеры также могут использовать JIT-компиляцию для преобразования Wasm в оптимизированный машинный код, что повышает производительность.
Интеграция с JavaScript
Wasm модуль может вызываться из JavaScript, а JavaScript функции могут вызываться из Wasm. Это достигается с помощью специальных интерфейсов и библиотек, таких как wasm_bindgen, которые обеспечивают взаимодействие между кодом на Rust (или других языках) и JavaScript.
Таска пока в беклоге т.к. на нее нет времени (как и особой нужды)
В связи с тестами Элизы скорее всего перенесем некоторые утилиты на бэк (как раз те, которые наиболее сложные).
Если коротко:
- Новая платформа (bun) вместе с фреймворком ElysiaJS работают чуть ли не быстрее (а иногда и быстрее) сервера на расте и go (fiber)
- В связи с этим для поддержки экосистемы (единые типы, яызк) можно не переписывать на Rust и другие языки т.к. потратим время, а в итоге профита может и не быть.
Скрины от разработчика (-ов) Elysia
В левой консоли всегда Элиза, справа Раст на двух платформах и go (fiber)
Еще больше тестов - SaltyAom/bun-http-framework-benchmark
'+' в комменты если остаёмся на Elysia (@Kopchan / @Zamelane)
+++
see #91 (comment)