性能
このページでは、WaaS を他のスクリプトエンジンや WebAssembly ランタイムと比較します。結果は WaaS.Benchmarks で再現できます。
インタプリタのバックエンド
| バックエンド | 使われる条件 |
|---|---|
| Burst | Unity で com.unity.burst が導入されており、Burst が対応するプラットフォームであるとき |
| Managed | それ以外(.NET、Burst のない Unity) |
Burst のバックエンドを使うためにコードを変更する必要はありません。デバッガの使用中は、命令を 1 つずつ実行する低速なインタプリタで動作します。
Burst がない場合、IL2CPP ではインタプリタの最適化の効果が CoreCLR より小さくなります。IL2CPP で性能が重要な場合は com.unity.burst を導入してください。
計測の条件
Windows 11、Intel Core i7-13700F。Unity 6000.5.8f1 の非開発ビルドの IL2CPP プレイヤー、.NET 10、xLua(59bf426、Lua 5.3)、Lua-CSharp 0.5.8、wasmtime 50.0.1、wasm3(28ecb9a、clang でビルド)。各値は、交互に 4 回実行したときの中央値のうち最小のものです。
同じ処理を Rust、MoonBit、Lua で実装しており、すべての実装のチェックサムが一致することをハーネスが検証します。wasm3 と wasmtime は .NET の外で動作するため、計算の処理のみを計測しています。
| 処理 | 内容 |
|---|---|
| fib | 再帰によるフィボナッチ数(30) |
| sieve | 1,000,000 までのエラトステネスの篩 |
| mandelbrot | 200 × 200 の格子のマンデルブロ集合 |
| strings | 20,000 個の文字列の整形、分割、ハッシュ |
| sort | 200,000 個の整数の整列 |
| map | ハッシュマップへの 500,000 回の挿入 |
WebAssembly ランタイムとの比較
計算の処理(ms、小さいほど高速)。wasmtime は JIT コンパイラであり参考値です。wasm3 はインタプリタです。
ゲスト言語による時間の差は処理によって異なります。
| Workload | WaaS CoreCLR (Rust) | WaaS CoreCLR (MoonBit) | WaaS Burst (Rust) | WaaS Burst (MoonBit) | wasm3 (Rust) | wasm3 (MoonBit) | wasmtime (Rust) | wasmtime (MoonBit) |
|---|---|---|---|---|---|---|---|---|
| fib | 34.1 | 65.4 | 19.7 | 44.6 | 17.9 | 26.4 | 2.0 | 3.8 |
| sieve | 40.2 | 176.8 | 42.0 | 111.0 | 19.0 | 78.0 | 2.3 | 5.1 |
| mandelbrot | 16.5 | 36.2 | 16.4 | 38.1 | 7.3 | 15.5 | 1.7 | 2.2 |
| strings | 40.8 | 518.7 | 60.9 | 524.4 | 16.3 | n/a | 2.2 | 16.9 |
| sort | 64.2 | 357.1 | 56.4 | 309.1 | 23.9 | 144.5 | 4.6 | 19.8 |
| map | 81.2 | 613.7 | 79.4 | 417.0 | 36.7 | 232.3 | 4.4 | 20.0 |
n/a: wasm3 がこのモジュールの関数をコンパイルできません。
Lua との比較
計算の処理(ms、小さいほど高速)。
| Workload | xLua | Lua-CSharp |
|---|---|---|
| fib | 49.3 | 393.3 |
| sieve | 33.4 | 230.4 |
| mandelbrot | 32.6 | 182.0 |
| strings | 24.8 | 181.3 |
| sort | 50.2 | 154.5 |
| map | 8.8 | 70.1 |
スクリプトとホストの間の呼び出し
単位は ns/call で、小さいほど高速です。ffi_* はスクリプトからホスト、callback_* はホストからスクリプトの呼び出しです。
| Workload | WaaS CoreCLR (Rust) | WaaS CoreCLR (MoonBit) | WaaS Burst (Rust) | WaaS Burst (MoonBit) | xLua | Lua-CSharp |
|---|---|---|---|---|---|---|
| ffi_nop | 40 | 46 | 58 | 70 | 27 | 207 |
| ffi_add | 51 | 44 | 69 | 83 | 40 | 413 |
| ffi_string_in | 76 | 251 | 404 | 1,008 | 114 | 304 |
| ffi_string_out | 307 | 2,349 | 805 | 3,139 | 67 | 259 |
| ffi_struct | 115 | 1,646 | 374 | 1,694 | 94 | 362 |
| ffi_resource | 154 | 85 | 333 | 347 | 31 | 318 |
| callback_add | 128 | 95 | 469 | 466 | 30 | 373 |
| callback_string | 337 | 1,436 | 967 | 2,837 | 68 | 361 |
- MoonBit の文字列は UTF-16 であり、バインディングの UTF-8 向けの直接の経路を通りません。また、バインディングがゲスト側でメモリを確保します。
- 文字列と record は、ゲストのメモリに格納するため、数値より時間がかかります。
ロード
単位は ms で、小さいほど高速です。
| Engine | Engine init | Load | Instantiate | First call | Total |
|---|---|---|---|---|---|
| WaaS, first in a process | 0.000 | 12.003 | 2.627 | 0.893 | 15.524 |
| WaaS (MoonBit), first in a process | 0.000 | 11.797 | 2.714 | 0.097 | 14.608 |
| xLua, first in a process | 6.551 | 0.098 | 0.799 | 0.084 | 7.533 |
| xLua (bytecode), first in a process | 6.501 | 0.021 | 0.804 | 0.083 | 7.409 |
| Lua-CSharp, first in a process | 0.782 | 1.833 | 0.246 | 0.012 | 2.873 |
| WaaS, repeated | 0.000 | 6.249 | 0.588 | 0.034 | 6.871 |
| WaaS (MoonBit), repeated | 0.000 | 5.018 | 0.267 | 0.005 | 5.290 |
| xLua, repeated | 0.841 | 0.090 | 0.724 | 0.005 | 1.661 |
| xLua (bytecode), repeated | 0.940 | 0.018 | 0.713 | 0.003 | 1.674 |
| Lua-CSharp, repeated | 0.030 | 0.321 | 0.017 | 0.002 | 0.370 |
| WaaS CoreCLR (Rust), repeated | - | - | - | - | 9.724 |
| WaaS CoreCLR (MoonBit), repeated | - | - | - | - | 5.070 |
| wasm3 (Rust), repeated | - | - | - | - | 0.014 |
| wasm3 (MoonBit), repeated | - | - | - | - | 0.026 |
| wasmtime (Rust), repeated | - | - | - | - | 23.618 |
| wasmtime (MoonBit), repeated | - | - | - | - | 20.037 |
- component のロードでは、すべての関数の検証と変換を行うため、時間は component のサイズに応じて増えます。
- wasm3 は関数を最初の呼び出しのときにコンパイルします。この時間は値に含まれません。
- IL2CPP の初回のロードには、ランタイムの初期化が含まれます。
結果の読み方
- デスクトップの x64 CPU での比較です。他のプラットフォームは計測していません。
- 結果はコンパイラがゲストに生成するコードに左右されます。たとえば
mapでは、ゲストのハッシュ関数をインタプリタで実行する一方、Lua は C で実装されたテーブルを使います。 - 性能はエンジンの選択の一要素です。WaaS にはサンドボックス、ゲスト言語の選択肢、JIT が不要であることなどの特徴もあります。