メインコンテンツまでスキップ

性能

このページでは、WaaS を他のスクリプトエンジンや WebAssembly ランタイムと比較します。結果は WaaS.Benchmarks で再現できます。

インタプリタのバックエンド​

バックエンド使われる条件
BurstUnity で 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)
sieve1,000,000 までのエラトステネスの篩
mandelbrot200 × 200 の格子のマンデルブロ集合
strings20,000 個の文字列の整形、分割、ハッシュ
sort200,000 個の整数の整列
mapハッシュマップへの 500,000 回の挿入

WebAssembly ランタイムとの比較​

計算の処理(ms、小さいほど高速)。wasmtime は JIT コンパイラであり参考値です。wasm3 はインタプリタです。

WaaS、xLua、Lua-CSharp、wasm3、wasmtime の計算の処理の時間(対数軸)

ゲスト言語による時間の差は処理によって異なります。

WaaS、wasm3、wasmtime での Rust と MoonBit のゲストの時間(対数軸)

WorkloadWaaS CoreCLR (Rust)WaaS CoreCLR (MoonBit)WaaS Burst (Rust)WaaS Burst (MoonBit)wasm3 (Rust)wasm3 (MoonBit)wasmtime (Rust)wasmtime (MoonBit)
fib34.165.419.744.617.926.42.03.8
sieve40.2176.842.0111.019.078.02.35.1
mandelbrot16.536.216.438.17.315.51.72.2
strings40.8518.760.9524.416.3n/a2.216.9
sort64.2357.156.4309.123.9144.54.619.8
map81.2613.779.4417.036.7232.34.420.0

n/a: wasm3 がこのモジュールの関数をコンパイルできません。

Lua との比較​

計算の処理(ms、小さいほど高速)。

WorkloadxLuaLua-CSharp
fib49.3393.3
sieve33.4230.4
mandelbrot32.6182.0
strings24.8181.3
sort50.2154.5
map8.870.1

スクリプトとホストの間の呼び出し​

単位は ns/call で、小さいほど高速です。ffi_* はスクリプトからホスト、callback_* はホストからスクリプトの呼び出しです。

スクリプトとホストの間の呼び出しの時間(対数軸)

WorkloadWaaS CoreCLR (Rust)WaaS CoreCLR (MoonBit)WaaS Burst (Rust)WaaS Burst (MoonBit)xLuaLua-CSharp
ffi_nop4046587027207
ffi_add5144698340413
ffi_string_in762514041,008114304
ffi_string_out3072,3498053,13967259
ffi_struct1151,6463741,69494362
ffi_resource1548533334731318
callback_add1289546946630373
callback_string3371,4369672,83768361
  • MoonBit の文字列は UTF-16 であり、バインディングの UTF-8 向けの直接の経路を通りません。また、バインディングがゲスト側でメモリを確保します。
  • 文字列と record は、ゲストのメモリに格納するため、数値より時間がかかります。

ロード​

単位は ms で、小さいほど高速です。

EngineEngine initLoadInstantiateFirst callTotal
WaaS, first in a process0.00012.0032.6270.89315.524
WaaS (MoonBit), first in a process0.00011.7972.7140.09714.608
xLua, first in a process6.5510.0980.7990.0847.533
xLua (bytecode), first in a process6.5010.0210.8040.0837.409
Lua-CSharp, first in a process0.7821.8330.2460.0122.873
WaaS, repeated0.0006.2490.5880.0346.871
WaaS (MoonBit), repeated0.0005.0180.2670.0055.290
xLua, repeated0.8410.0900.7240.0051.661
xLua (bytecode), repeated0.9400.0180.7130.0031.674
Lua-CSharp, repeated0.0300.3210.0170.0020.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 が不要であることなどの特徴もあります。