Для тех из вас, кто не знаком с миром разработки, ходят слухи, что есть новый тип кода, который может стать будущим веб-разработки, под названием WebAssembly (Wasm). Wasm — это низкоуровневый язык, похожий на ассемблер, который позволяет разработчику писать в Интернете на нескольких языках (C/C++/Rust) почти с родной скоростью. Wasm разработан, чтобы дополнять работу с JavaScript, поэтому он не предназначен для замены. Для опыта и примеров в этом посте я буду использовать C и Rust для компиляции в Wasm и использовать JavaScript для их запуска. Для тех, кто не знает Rust, это язык системного программирования, который работает невероятно быстро, предотвращает ошибки сегментации и гарантирует безопасность потоков.
Моя первоначальная попытка изучения Rust + WebAssembly (Wasm) была связана с микротестированием, чтобы лично убедиться, станет ли это будущим веб-разработки и будет ли оно быстрее, чем нативный JavaScript (JS). Он собирался заниматься обработкой простой математики, сложной математикой, обработкой изображений и анализом.
Нет.
Это был такой опыт…
Минимальный рабочий пример от Hello, Rust!
Я использовал установку wasm32-unknown-unknown (уже был установлен Rust) и попробовал Минимальный рабочий пример от hellorust. Будучи новичком в Rust и Wasm, я понятия не имел, что делаю, но слепо следовал инструкциям. Взяв первые несколько команд из Минимального рабочего примера:
Мои вопросы новичка
- Что означает
wasm32-unknown-unknown
? - Что означает
cdylib
? - Что делает
wasm-gc
и почему существуетbig.wasm
?
Ответы
- Выяснил, что это означает
{architecture}-{vendor}-{system}
и это ржавчина-крест. Это помогает кросс-компилировать программы Rust для разных машин. cdylib
означает экспорт интерфейса C из динамической библиотеки Rust, который впоследствии можно использовать для компиляции в Wasm для интерпретации всеми браузерами (rfcs).- Расширение
big.wasm
— это просто способ назвать файл.wasm
, который включает в себя ненужные операции экспорта, импорта и т. д. Командаwasm-gc
берет на себя очистку от лишнего кода (wasm-gc).
После нескольких (может быть, 2–3 часов) изучения того, какие инструменты я использую, что они делают и что происходит, вот результат этого. Мой код на github. Чтобы запустить его, просто откройте файл index.html
в браузере.
Васм-пак
Wasm-pack — это инструмент, который упаковывает код Rust в пакет NPM для последующей публикации и использования.
Именно эта статья привлекла меня в wasm-pack. Когда я узнал о wasm-pack, я подумал про себя: О! Это упростит компиляцию кода Rust, и все, что мне нужно сделать, это опубликовать пакет NPM и использовать его.
Ха-ха… да, нет.
Я следовал этому руководству по использованию wasm-pack для создания/публикации моего первого пакета Rust NPM. Инструкции и шаги были очень четкими и понятными. Я не столкнулся ни с какими проблемами… кроме одной.
При запуске команды wasm-pack init --scope MYSCOPE
файла wasm и файла-оболочки JS вокруг файла wasm не было.
После еще нескольких часов возни, отладки, тестирования на Mac и Windows, поиска компьютера с Linux и размышлений о покупке нового компьютера я решил опубликовать проблему на странице GitHub.
Моя проблема была решена с помощью одного из участников wasm-pack. Ура! Мой первый вклад в открытый исходный код! (косвенно?… вроде? Нет? Хорошо)
Когда моя проблема с не компилируемыми файлами-оболочками .wasm
и js
не была решена, я смог опубликовать пакеты NPM здесь. Отлично. Давайте перейдем к простому математическому сравнению Rust + Wasm и JS.
На этом графике представлена разница во времени между всеми различными способами реализации дополнительных функций. По какой-то причине для Inline Wasm было записано постоянное время 0,0 мс для каждого выполнения. Я считаю, что это ошибка, но так и не докопался до сути. Поэтому пришлось провести дополнительные испытания.
Вывод, который я сделал из этого конкретного эксперимента, заключался в том, что может быть много вызовов FFI (интерфейс внешних функций), на которые я ссылаюсь, что может дать больше места для ошибок, чем мне хотелось бы.
Исходник здесь.
ВасмФиддл
Чтобы попытаться избежать ошибки, я решил провести еще один простой арифметический микро-бенчмаркинг. Я использую WasmFiddle в качестве своего онлайн-редактора, так что и код Wasm, и код JS живут в одной и той же области и должны иметь некоторую единообразие за кулисами. На этот раз я реализовал функциональность модуля и буду использовать C + Wasm и JS.
Теперь ЭТО имеет более многообещающие результаты. Судя только по графику, у Inline Wasm явное преимущество. Приближение ко второму месту, похоже, является компромиссом между Wasm и Inline JS.
Исходник здесь.
Из этих результатов я пришел к выводу, что Wasm будет чем-то, что стоит изучить глубже и создать больше приложений с Wasm, чтобы увидеть все преимущества, которые он приготовил для нас. Конечно, не говоря уже о том, что мне все еще нужно провести еще несколько тестов и экспериментов, чтобы проверить, когда Wasm может быть быстрее, а когда JS — быстрее.
Судя по статьям, которые я читал, Wasm будет окончательным выбором, когда речь идет о более жестких веб-приложениях, требующих больших вычислительных ресурсов, таких как обработка изображений или игры с более чистой графикой. "Вот несколько примеров.
Моими следующими шагами будет немного больше микро-бенчмаркинга для себя, например, сравнение скорости парсинга данных Rust + Wasm по сравнению с JS, так как я слышал, что Rust очень хорошо справляется с парсингом. После этого я, вероятно, буду использовать его для создания некоторых веб-приложений, чтобы протестировать его.
В заключение, я не думаю, что это интуитивно понятно, когда вы начинаете использовать Wasm, особенно с Rust, поскольку оба они все еще находятся в стадии разработки. Однако, немного поработав с ними, я вижу, насколько мощным и простым будет их использование в будущем.
Другие источники:
WebAssembly в 30 раз быстрее, чем JavaScript
Начало работы с Rust, WebAssembly и Webpack
Первоначально опубликовано на www.pmg.com 10 мая 2018 г.