Для тех из вас, кто не знаком с миром разработки, ходят слухи, что есть новый тип кода, который может стать будущим веб-разработки, под названием 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, я понятия не имел, что делаю, но слепо следовал инструкциям. Взяв первые несколько команд из Минимального рабочего примера:

Мои вопросы новичка

  1. Что означает wasm32-unknown-unknown?
  2. Что означает cdylib?
  3. Что делает wasm-gc и почему существует big.wasm?

Ответы

  1. Выяснил, что это означает {architecture}-{vendor}-{system} и это ржавчина-крест. Это помогает кросс-компилировать программы Rust для разных машин.
  2. cdylib означает экспорт интерфейса C из динамической библиотеки Rust, который впоследствии можно использовать для компиляции в Wasm для интерпретации всеми браузерами (rfcs).
  3. Расширение 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

Демо — Привет, Раст!

потрясающий-wasm

Первоначально опубликовано на www.pmg.com 10 мая 2018 г.