Diary-SPO / core

Дневник СПО — обёртка над дневником Сетевого города для СПО Томской области

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BREAKING CHANGE: переписать утилиты на Rust / C# с интеграцией через Wasm

scffs opened this issue · comments

В чём суть

  1. Утилита (функция), написанная на расте, будет работать в разы быстрее того же JS
  2. Через WebAssembly идет конвертирование кода на Rust в бинарник, который потом запускается в виртуальной машине в браузере.
  3. Для доп. перфоманса можно вынести в воркер, но не думаю, что есть нужда

Тут могут быть подводные камни в виде:

  1. Слишком мелкая разница. В итоге мы зря потратим время
  2. Станет хуже. У нас появляется прослойка в виде 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

Интерпретация и компиляция

  1. Интерпретация: Браузер загружает и интерпретирует бинарный код Wasm с помощью встроенной виртуальной машины.

  2. Компиляция Just-in-Time (JIT): Браузеры также могут использовать JIT-компиляцию для преобразования Wasm в оптимизированный машинный код, что повышает производительность.

Интеграция с JavaScript

Wasm модуль может вызываться из JavaScript, а JavaScript функции могут вызываться из Wasm. Это достигается с помощью специальных интерфейсов и библиотек, таких как wasm_bindgen, которые обеспечивают взаимодействие между кодом на Rust (или других языках) и JavaScript.

Таска пока в беклоге т.к. на нее нет времени (как и особой нужды)

В связи с тестами Элизы скорее всего перенесем некоторые утилиты на бэк (как раз те, которые наиболее сложные).

Если коротко:

  1. Новая платформа (bun) вместе с фреймворком ElysiaJS работают чуть ли не быстрее (а иногда и быстрее) сервера на расте и go (fiber)
  2. В связи с этим для поддержки экосистемы (единые типы, яызк) можно не переписывать на Rust и другие языки т.к. потратим время, а в итоге профита может и не быть.

Скрины от разработчика (-ов) Elysia

В левой консоли всегда Элиза, справа Раст на двух платформах и go (fiber)

image

image

image

Еще больше тестов - SaltyAom/bun-http-framework-benchmark


'+' в комменты если остаёмся на Elysia (@Kopchan / @Zamelane)