C# vs. Wren

自作C++エンジンTristeonにはスクリプトの仕組みがありませんでした。採用を決める前に、有力な二つの候補を計測しました。Luaに近い小さな組み込み言語のWrenと、業界標準ながらC++への組み込みが難しいC#です。

C++ · C# · Wren · ベンチマーク

三つの観点

実行速度は当然重要ですが、エンジンにとってはそれだけではありません。次の三つを計測しました。

  • 実行性能:四則演算、リストへの追加、ユーザー定義型の生成をそれぞれ10万回。
  • コンパイル時間:変更が実行可能になるまでの時間。デザイナーの試行錯誤の速さを左右します。
  • C++呼び出しのコスト:言語の境界をまたぐ呼び出し一回あたりのコスト。エンジンのスクリプトはほとんどこれで成り立っています。

WrenはCライブラリなので薄いC++ラッパーだけで済みます。C#の選択肢はP/Invoke、COM相互運用、埋め込み相互運用型、Monoによるホスティングでした。

// Arithmetic (C#)
for (int i = 0; i < 100000; i++)
{
    int x = 0, y = 10;
    int result = x * y / (i + 1);
}

// Collections (Wren)
var items = []
for (i in 1..100000) {
    items.add(i * i)
}

結果

四則演算(µs・小さいほど良い)

Wren7,910
C#726

リスト(µs・小さいほど良い)

Wren4,912
C#779

オブジェクト生成(µs・小さいほど良い)

Wren31,000
C#2,105

コンパイル時間(µs・小さいほど良い)

Wren53
C#88,000

C++の呼び出し(ms・小さいほど良い)

Wren< 1
C#117

計測方法:実行性能のベンチマークは上のループ(10万回)を、両言語で同じように書いたものです。大学での短い調査であり本格的なベンチマークではないため、結果は正確な値ではなく桁の目安として見てください。こうした数値はハードウェア、ランタイムのバージョン、JITのウォームアップによって変わります。


勝ち負けではなくトレードオフ

C#は6〜15倍速く動作しました。一方Wrenはコンパイルが1000倍以上速く、C++の呼び出しもほぼゼロコスト。C#は境界をまたぐたびに無視できないコストがかかりました。

つまり、正解はスクリプトの役割次第です。エンジンのゲームプレイスクリプトの多くはエンジンの機能同士をつなぐもので、C++を頻繁に呼び出し、頻繁に書き換えられます。これはWrenの安い呼び出しコストと即時の反復に向いています。重い計算はどちらにせよC++で書くべきです。


← ポートフォリオに戻る