世界を動かす技術を、日本語で。

UnityのMono問題:なぜあなたのC#コードは期待よりも遅く動作するのか

2025年12月29日原文(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正式対応予定、今後の動向に注目。

Hackerたちの意見

うーん、UnityはもうCoreCLRへの移行に必要な技術力がない気がする。遅れ続けてるし、技術リーダーもどんどん辞めてるしね。https://github.com/stride3d/stride なんかどう?もう.NET 10に対応してるし、Unityみたいにクロスバウンダリーのオーバーヘッドもないよ。

進捗は遅々としてるけど、Unityは前に進んでるみたい。Unityの計画と進捗についての更新: 2022年 - CoreCLRへの移行を公式に発表 - https://unity.com/blog/engine-platform/unity-and-net-whats-n... 2023年 - テクニカルアップデート - https://unity.com/blog/engine-platform/porting-unity-to-core... Unite 2025 - CoreCLRベースのプレイヤーが2026年のUnity 6.7に予定されてる - https://digitalproduction.com/2025/11/26/unitys-2026-roadmap...

StrideはUnityの機能のほんの一部しかないよ。Godotが唯一の本当のオープンソースの競争相手だけど、C#のサポートがイマイチなんだよね。Webにビルドできないなら、ゲームジャムには役立たないし、誰もランダムなバイナリをダウンロードして実行するべきじゃないからね。本当にGPUサポートのあるサンドボックスソリューションが必要だよ。

購入した「アドオン」のサポートを削除して書き直すことを、買い物をした人たちに伝えなきゃいけないと想像してみて。そしたら、株主や顧客に「wecan」の価値の低下と、同じ機能を回復するためのコストを説明しなきゃいけない。買収した企業の技術の寄せ集めは、どんな技術リーダーにとっても厄介な問題で、書き直しはCEOのキャリアを終わらせることになる。

記事には書いてないけど、Unityが使ってるGCは.NETやスタンドアロンのMonoに比べてパフォーマンスがすごく悪いんだ。Boehm GCを使ってるからね。最後に聞いたとき、UnityはIL2CPPをもっと良いGCに切り替える予定はないみたいだよ。[1] CoreCLRエディタのパフォーマンスがどうなるか楽しみだね。これだけ速度差があると、エディタで動かす方がスタンドアロンのMono/IL2CPPビルドよりも良くなるかもしれない。

Boehm GCを使ってるからね。 なんで?Monoはかなり良い精密GCを持ってるのに、もう何年も前から。

エディタのスピードアップについてだけど、「ドメインリロード」ってやつを完全に排除できるはずだよ。C#が変更に応じてアンロードされて再ロードされる必要があるからね。

一方で、より良いGCは確かにいいけど、もう一方ではそれほど重要じゃないかも。フレームごとのアロケーションはゼロにしたいし、それは多分変わらないだろう。あまり頻繁に発生しないガベージがインクリメンタルGCを上回らなければ、特に問題にはならない。意図通りにインクリメンタルに動いていれば、カクつきも問題ないはず。ゲームでは、サーバーインスタンスのように常にリクエストを増やせるわけじゃないから、GCのスループットが無限に良くなるわけじゃない。

最近Godotを学び始めたんだけど、C#ランタイムに.NETを使ってるのはいいね。仕事で.NETをターゲットにしたコードを書くことが多いから、Unityのやり方を学ぶのはちょっとストレスだよ。

2018年にUnityのエンジニアたちがエンジンを.NET CoreCLRに移植する作業をしていると話してた。 確かに大変な作業だね。Unityはこの問題に全力を注ぐ必要があるよ。C#はデフォルトでめちゃくちゃ速くなってるから、アップグレードする価値はすごくある。私たちはサイズやAPIの面では比較にならないけど、472からdotnet6に移行するのに数ヶ月かかった。でも、一旦dotnet6に移ったら、その後のLTSへの移行は比較的楽だったよ。通常は数時間の作業で済んだ。

Unityには統一性の問題があるね。何かを作るのは簡単だけど(機能は盛りだくさん)、モノリス問題にも悩まされてる(機能が多すぎて、古いコードや技術的負債がある)。アセットストアは素晴らしいけど、技術的にはちょっと洗練されてない感じ。始まった頃から比べれば格段に進化したけど、重いスクリプトの修正なしではなんか空虚な感じがするんだよね。それが問題なんだ。モノに基づいたスクリプトの設計はCoreCLRにうまく移行できないし、同じBehaviorインターフェースを使うのも少し複雑になってる。時には(自分のエンジンでも)古いものを手放して新しいものを始める必要がある。Dx7からdx9、dx9からopengl、openglからvulkan、vulkanからwebgpu。追記:数分後に考えたんだけど、もしUnityが本当にコアを大事にしてるなら、Blenderが3.Xでやったみたいにエディタを完全にリニューアルするべきだと思う。レベルエディタやプレハブメーカーにもっと考慮を払って、異なるワークフロービューを提供してほしい。編集 / アニメーション / スクリプティング / レンダリング / ポスト。今のままじゃ、1999年スタイルのプロパティウィンドウが横にあるだけの、単一ビューで物を生成するメニュー項目に過ぎない。

最後のステップは意味不明だね。WebGPUはVulkanに似たシムレイヤーで(WebGLがGLESに似ているのと同じように)、OSのネイティブGPGPU時代のAPIを使えるようにしてくれる。適切なOSでは、WebGPUはすべての呼び出しをVulkanに1:1で変換して、かなり安価に処理してる。Windowsでは、ブラウザがGPUベンダーによってこれを行うけど、NvidiaはVulkanのパフォーマンスがあまり良くないし、DX12と同じパフォーマンスが出るべきところでもそうじゃない。AMDはこのバグに悩まされていない。パフォーマンスを気にするなら、Vulkanを直接呼び出してオーバーヘッドを払う必要はない。ポータビリティを気にするか、WASMターゲットにコンパイルするなら、ほぼWebGPUに制限されて、そのペナルティを払わなきゃいけない。余談だけど、WindowsドライバーやLinuxのMesaがWebGPUの実装を提供するのを妨げるものはないから、ブラウザはそういったドライバーに独自のシム実装を必要とせず、翻訳オーバーヘッドも発生しないはずなんだ。でも、実際にはそうなってない。

Hacker Newsで議論の続きを見る