❄️

WinterJSとは何者か?ベンチマークでの比較検証

2024/03/13に公開1

概要

2024年3月12日にこんなニュースが飛び込んできました。
WinterJSの1.0が発表されたとのことで、今回はWinterJSとは何者なのかについてをまとめていき、検証していきます。

https://wasmer.io/posts/winterjs-v1

WinterJS

WinterJS とは、Rustで書かれたJavaScriptランタイムでSpiderMonkeyエンジンを使用して、javaScriptを実行します。

Rustで書かれたと言っているのは、HTTPリクエストなどの処理や、JavaScriptイベントのループを処理をするRust の非同期ランタイムTokioを使用しているからです。

https://tokio.rs/

また、WinterJSは、WebAssemblyにコンパイルすることもできるようです。

そして、一番重要なことは、JavaScriptにおけるHTTP Serverとしての性能について、処理速度がとんでも無く早いということを謳っている点ですね。
今回は、私も実際のベンチマークがどうなのかを検証してみたく、WinterJS / Bun / WorkerD / Nodeで比較していこうと思います。

また、特徴的なのは既存でよく使われるWebフレームワークもサポートしており、今だと Next.js、Nuxt.js、Hono、Astro、SvelteKit、Remix などをサポートしているとのことです。

SpiderMonkey

SpiderMonkeyは、Mozilla の JavaScript および WebAssembly エンジンであり、皆さんがよく使われているであろうFirefoxにも使用されています。
Webブラウザは、JavaScriptを実行するためのJavaScriptエンジンが組み込まれているわけですが、例えば
Chromeだと「V8」と呼ばれるものだったりするわけです。

https://spidermonkey.dev/

話は戻り、WinterJSは、Cloudflare Workers や Deno Deploy、Vercelなどのサービスとの互換性を目指すために、WinterCG 仕様というものに準拠しています。

WinterCG

WinterCGとは、Web-interoperable Runtimes Community Groupの略で、Node.jsやDenoまたは、エッジランタイム(Cloudflare WorkersやDeno)上でWebプラットフォームAPIを使用することに興味があるコミュニティとのことです。

参加メンバーとしては、個人もいるし、下記の組織の所属しているメンバーもいるとのことです。

Bloomberg
Cloudflare
Deno
Fastly
Igalia
Netlify
Node.js
Shopify
Vercel
Suborbital

活動としては、ランタイム全体でWebプラットフォームAPIの改善のためにいろいろな取り組みをやっているとのことです。
例えば、Web プラットフォーム API の最小限のコレクションをRepositoryで公開していたり、サーバーサイドのJavaScript環境にアップストリーム仕様を適したものにするための WHATWG Fetchをフォークしたものなどや、暗号化、ソケットAPIなどを公開しております。

https://github.com/wintercg/proposal-common-minimum-api

https://github.com/wintercg/fetch

https://github.com/wintercg/proposal-webcrypto-streams

https://github.com/wintercg/proposal-sockets-api

Wasmer

今回のプレスの中でも語られていたこととして、WinterJSというものが、Wasmer Edgeで完全に実行可能な最初の実稼働グレードのランタイムであると記載があるのですが、このWasmerというのを初めて聞いた方もいるのではないでしょうか?
実は、WinterJS自体もこのWasmer社で開発されたものです。

https://wasmer.io/

https://docs.wasmer.io/

Wasmer は、WebAssembly に基づくエコシステムであり、エコシステムとしていくつかサービスを提供しています。

  • Wasmer Runtime : Wasmerコンテナをどこでも実行できるようにします
  • Wasmer Registry : コミュニティからコンテナを探し、独自のコンテナを配布します
  • Wasmer Edge : Wasmer分散エッジ上でコンテナを実行します
  • Wasmer JavaScript SDK : Wasmer分散エッジ上でコンテナを実行します

WinterJS / Bun / WorkerD / Node でのベンチマーク検証

プレスの中でも語られていたのは、その処理速度の速さにあります。性能として、より多くのリクエストを捌けると歌っており、今回はそのベンチマークの性能がどうなのかも検証していきます。

WinterJS 1.0 は、ネイティブで実行すると150,000 リクエスト/秒を処​​理できます( WASIXを使用して Wasm にコンパイルすると、20,000 リクエスト/秒)。
現在、WinterJS は、 Bun : 117k reqs/s、WorkerD : 40k reqs/s、およびNode 75k reqs/sよりも多くのリクエストを 1 秒あたり処理できます。

ベンチマークでの検証

前提条件

  • 性能を検証した日付: 2024/3/13
  • 検証に使用したPC: MacBook Air M1ラップトップ

比較する対象

  • workerd
  • Bun
  • Node
  • WinterJS WASIX (WASIX 経由で Wasmer で実行される WinterJS)
  • wrangler

検証をする

今回は、HTTP ベンチマークツールとして、wrk を使用します。

https://github.com/wg/wrk

wrkの使い方なのですが、簡単で下記のオプションを使用しリクエストの負荷が高い状況を作り出します。

  • t: 指定した数はスレッド数
  • c: 指定した数はhttp connectionの数
  • d: 指定した数は実行する時間(ここでは、10秒)

下記で提供されているbenchmarkで用意されているサンプルコードをローカル環境で起動し、ベンチマークをwrkで計測していきます。
https://github.com/wasmerio/winterjs/tree/main/benchmark

実際に比較検証ではどんなことをやるのかというと、responseに"hello"を返す、HTTPサーバを立てて、12スレッド、 400のhttp connectionを指定し、実行時間を10sとし、その結果を見ていきます。

workerd

V8 を搭載した Cloudflare の Service Worker サーバー

https://github.com/cloudflare/workerd

サーバの起動方法

./workerd-darwin-arm64 serve ./worker.capnp

計測

❯ wrk -t12 -c400 -d10s http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.58ms    2.13ms  43.15ms   97.89%
    Req/Sec     2.49k     1.33k    5.46k    68.17%
  297857 requests in 10.02s, 23.58MB read
  Socket errors: connect 0, read 429, write 0, timeout 0
Requests/sec:  29721.09
Transfer/sec:      2.35MB

Bun

https://bun.sh/

サーバの起動方法

> bun ./bun-simple.js

計測

❯ wrk -t12 -c400 -d10s http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.64ms    1.16ms  58.53ms   96.14%
    Req/Sec    12.79k     1.82k   18.75k    89.92%
  1528300 requests in 10.02s, 174.90MB read
  Socket errors: connect 0, read 396, write 0, timeout 0
Requests/sec: 152587.55
Transfer/sec:     17.46MB

Node

https://nodejs.org/en

サーバの起動方法

> node ./node-simple.js

計測

❯ wrk -t12 -c400 -d10s http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.14ms  725.36us  37.02ms   97.92%
    Req/Sec     5.38k   464.22     5.66k    98.00%
  642642 requests in 10.01s, 105.41MB read
  Socket errors: connect 0, read 389, write 0, timeout 0
Requests/sec:  64211.26
Transfer/sec:     10.53MB

WinterJS WASIX

https://github.com/wasmerio/winterjs

サーバの起動方法

> wasmer run wasmer/winterjs --mapdir=/app:. --net -- /app/simple.js

計測

❯ wrk -t12 -c400 -d10s http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    15.11ms   15.81ms 171.41ms   82.70%
    Req/Sec     0.89k   336.30     1.68k    68.70%
  43749 requests in 10.08s, 5.01MB read
  Socket errors: connect 0, read 798, write 70, timeout 0
Requests/sec:   4341.86
Transfer/sec:    508.81KB

Wrangler

https://developers.cloudflare.com/workers/wrangler/

サーバの起動方法

> npx wrangler@3.15.0 dev ./simple.js

計測

❯ wrk -t12 -c400 -d10s http://127.0.0.1:8787
Running 10s test @ http://127.0.0.1:8787
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    90.74ms   47.27ms 294.60ms   81.74%
    Req/Sec   179.72     94.43   600.00     69.58%
  21596 requests in 10.08s, 1.71MB read
  Socket errors: connect 0, read 831, write 1, timeout 0
Requests/sec:   2142.66
Transfer/sec:    173.68KB

考察

私の環境では、WinterJS WASIXが一番早くなることはなく、Bunの性能が明らかにはやい結果になってしまった。
プレスリリースの内容を読むからに本当であればBunと同じ性能が出るはずなので、同じような性能は現時点では出ませんでした。(2024/3/13 時点)
少し時間を置き再度試してみて性能比較についてはチャレンジしてみようと思います。

最後に

個人的には非常に面白いものが出たなという印象で、WASIXによってWebAssemblyへのコンパイルができるかつRustで書かれたJavaScriptランタイムということで、今後の動向を見ていたいと思います。

引用元

https://wasmer.io/posts/winterjs-v1

https://tokio.rs/

https://spidermonkey.dev/

https://wintercg.org/faq

https://wasmer.io/

Discussion

たいち ひたいち ひ

コメント失礼します。

WinterJS が Bun のスコアを突破したのは WASIX を使用して Wasm にコンパイルされたものではなく、ネイティブで実行されたものかと思われます 🧐

cargo run --release -- ./simple.js

なので、実行コマンドはこのようなものになると思います。

そして Wasm コンパイル版は公式のベンチ結果でも相当スコアが低いので(確かまだ未最適化)、本記事のベンチ結果はおそらく正しい挙動になります。

ちなみにですが、ネイティブ版のベンチも少し事情がありそうですね