Web Systems

Fluid Simulator

JavaScript vs WebAssembly — CPU Performance Comparison

Fluid Simulator Screenshot

ブラウザ上でリアルタイム流体シミュレーションを動かし、 JavaScript と Rust/WebAssembly の CPU 計算パフォーマンスを比較する研究プロジェクトです。

Stable Fluids アルゴリズム(Jos Stam 氏)を同じパラメータで両方の言語に実装し、 WebGL によるカラフルな描画で結果を視覚化しています。

▶ デモを開くGitHub リポジトリ

技術スタック

TypeScriptRustWebAssemblyWebGL2ViteGitHub Actions

ベンチマーク結果

解像度JavaScriptWebAssembly倍率
N=128~14.7 ms~11.0 ms1.3x

※ Chromium (headless) / N=128 / CPU計算のみ(描画はWebGLで共通)

結論

"計算をWasmにすれば速くなる" は半分正解で半分間違い。

Stable Fluids のようなシンプルな数値計算では、モダンなJSエンジン(V8/SpiderMonkey)の JIT最適化が非常に強力で、Wasm化による恩恵は 1.2–1.3倍 程度にとどまりました。

Wasmが真価を発揮するのは、より大規模なグリッド(N=512+)、複雑な物理エンジン、 SIMD命令を活用できる処理、JS⇔Wasm境界越えの少ない長時間計算などの場面です。

開発で得た知見

Wasm は 1.2–1.3x 高速

シンプルな Stable Fluids アルゴリズムでは、モダンJSエンジンのJIT最適化が強力で、Wasm化の恩恵は限定的でした。

🐛

diffuse() の引数バグ発見

Rust実装で swap 後の読み書き方向が逆で、densityが毎ステップ0になる致命的バグを発見・修正しました。

🎨

WebGL 描画パイプラインの互換性

RGBA16F テクスチャを WebGL1 スタイルシェーダーで読めない問題を特定し、RGBA8 への移行で解決しました。

💡

密度保存と減衰のバランス

Navier-Stokes方程式はdensityを保存するため、decay(0.995/step)を導入して自然な流れを実現しました。

アーキテクチャ

CPU計算 (JS / Rust+Wasm) → テクスチャアップロード → WebGL2 描画
Stable FluidsJos Stam
HSV Color MapUint8 RGBA
PDG PipelineBloom + Shading