UnityのMono問題:なぜあなたのC#コードは期待よりも遅く動作するのか
109日前原文(marekfiser.com)
概要
- UnityのMonoランタイムは、現代の.NETと比較して大幅に遅い。
- .NET CoreCLRへの移行で、2~15倍の速度向上が期待できる。
- ゲームのビジネスロジックを分離し、直接比較したベンチマーク結果を紹介。
- CoreCLR導入は、パフォーマンスと開発効率の大幅な向上をもたらす。
- しかし、Unityの.NETモダナイゼーションはまだ生産環境向けではない状況。
UnityのMonoランタイムと.NETのパフォーマンス比較
- UnityはMonoフレームワーク上でC#コードを実行。
- 2006年当時、マルチプラットフォーム対応の.NET実装としてMonoが唯一の選択肢だった。
- 2014年以降、Microsoftが.NETをオープンソース化し、.NET CoreCLRが登場。
- .NET CoreCLRはパフォーマンスと機能面で大幅な進化を遂げている。
- 2018年からUnityもCoreCLR対応を進めているが、2026年まで本格運用は未定。
ベンチマーク結果
- ゲームのシミュレーションコードをUnity/Monoと**.NET**で比較。
- Unityエディタ(デバッグ): 100秒
- .NETユニットテスト(デバッグ): 38秒
- スタンドアロン(リリース)での比較
- Mono(リリース): 30秒
- .NET(リリース): 12秒
- .NETの方が2~3倍速いだけでなく、一部ワークロードでは10倍以上の差も観測。
パフォーマンス差の要因
- MonoのJIT(Just-In-Time)コンパイラが最適化不足。
- .NETは最新のJIT・最適化技術を活用。
- ベンチマークコードでは、Monoは式の単純化やインライン化が苦手で、.NETはループ外への最適化ができている。
Unityの.NETモダナイゼーションの意義
- CoreCLR導入でゲーム本体やUnity Editorのパフォーマンスが飛躍的に向上。
- 新しいC#機能や**Span<T>、ハードウェア命令(SIMD)**などの最適化APIが利用可能に。
- デバッグやテストの効率化、ドメインリロード不要化、GC(ガベージコレクション)の改善など、開発体験も向上。
- BurstのようなJIT最適化もCoreCLRでほぼ実現可能。
- iOSなどJIT禁止環境では、**IL2CPPによるAOT(事前コンパイル)**が引き続き採用される見込み。
現状の課題
- Unityは8年以上.NETモダナイゼーションに本腰を入れてこなかった。
- CoreCLRのAOTサポートは計画なし、引き続きIL2CPPが主流。
- CoreCLRへの全面移行はUnity 6.xロードマップに記載されたが、リリース時期は未定。
Monoと.NETのJIT最適化比較(技術詳細)
- テストコード:カスタム構造体の加算処理を大量ループで実行。
- .NET JIT生成コード
- ループ不変式の外出し、加算命令の最適化を自動で実施。
- int.MaxValue回のループが約750msで完了。
- Mono JIT生成コード
- 余計なメモリアクセスや命令が多数含まれる。
- ループ内での無駄なデータ移動・計算が多く、パフォーマンス低下の要因。
まとめと今後の展望
- Monoは.NETに比べて大幅にパフォーマンスが劣ることが明確。
- CoreCLR対応で、実行速度・開発効率・新機能活用が大きく前進。
- Unityの.NETモダナイゼーションが本格化すれば、業界全体に恩恵。
- それまでは、見えないコストとしてMonoの低速さがUnity開発者を悩ませ続ける状況。
- Unity開発者・ユーザーはCoreCLR導入を強く期待。
要点
- Unityの現行Monoランタイムはパフォーマンス面で時代遅れ。
- .NET CoreCLR移行で、2~10倍超の高速化が期待できる。
- 新機能・最適化APIの活用、開発効率向上も大きなメリット。
- 2026年以降にUnity 6.xでCoreCLR正式対応予定、今後の動向に注目。