高速なC#を書くために知っておくべきもの
主な編集履歴
2025/07/29
2025/07/28
2025/07/27
- リンクを基本そのまま貼るように変更
- C# docsを.NET documentationに変更
- Advanced .NET programming documentationnについて追加
- Compiler Explorerについて追加
- perf-bookについて追加(その他記事)
はじめに
C#を最適化するために知っておくべき情報源、ツール、コミュニティをまとめました。
具体的な最適化テクニックよりも、個人の経験をもとにどこで学び、どう検証するかに焦点を当てて紹介していきいます。
とにかく知ってもらうこと重視なので、解説は最低限。
ドキュメントを読んで。
筆者について
この記事の執筆時(2025年7月現在)、筆者はプログラミングとC#を学び始めて5年ほど、新卒1年目です。
コンピュータサイエンスの体系的な知識は専門ではなく十分ではありませんが、C#/.NETとその最適化について独学で学んできて、最近はCysharpさんによくPRを送ったり(ZLinqのAcknowledgementに載ったり)、C#上で動く処理系(Lua-CSharp、MRubyCS)を大幅に高速化したりなど、C#の高速化にはそれなりに詳しい自負があります。
記事でのアウトプットをもっとしていきたい...
実践でもっと強くなりたい...runtimeにもPRしていきたい...
C#/.NETを深く知るための情報源
筆者の主な情報源、おすすめブログなどの紹介
++C++; // 未確認飛行 C
とりあえず読みましょう。特にC# によるプログラミング入門は必読です。
管理人の岩永さん個人で運営しているので足りない部分などはIssue出しましょう。
.NET documentation
公式のdocs
- 機械翻訳がアレなのでja-jaならen-usに
- 一通りタイトルだけ見て、気になるところは全部読む
- APIのページ(例えばList<T>.Add)にSourceに飛べる項目がある。
- Advanced .NET programming documentationは結構深い
.NET Source Browser
BCL(Base Class Library)とroslynのSource検索
- ワンクリックで型、関数定義にjump
- ワンクリックで同じローカル変数をハイライト
Language Feature Status
新言語機能が現在どこまで進んでいるか
What's new in .NET
.NETの進化(Core以降)について、バージョンごとの新機能・改善点
.NET Blog # Performance Improvements in .NET
.NETの進化を書いた公式のブログ
ほぼ週刊 .NET WeekRef.NET
.NET関連の最新情報を日本語で週次配信。
- 更新情報は@mayukiで確認
- 海外の重要記事も日本語で紹介
その他記事
いろいろな記事、手法がまとまってます。
自分が参考にしていた見て欲しい記事などはだいたい紹介されてます。
上の記事にも紹介されていますが、改めておすすめ。
紹介された記事を書かれた方の他の記事を見たりするとよいですね。
CPU命令レベルの最適化になるとC/C++やアセンブラの最適化について調べることになります。
とか参考になるGitHub Repository
とにかくインプットは大事。
runtime
ランタイム本体。
- BCL(Base Class Library)
- runtime(C++)
- docs
活用方法
-
ソースコードの直接確認
- 例:List<T>.Addの実装
- コメントに最適化の理由が記載されていることが多い
- git blameでPRを追跡し、なぜその実装になったのか、議論の経緯を確認
-
ドキュメント
-
runtime/docs/design/coreclr
- ガベージコレクション
- JIT
- など...
- runtime/docs/design/features - 低レベル機能の詳細
- など...
-
runtime/docs/design/coreclr
neuecc氏作のライブラリ
UniTask/R3/ZLinq/MessagePack-CSharp etc...neuecc氏作の多くのハイパフォーマンス.NETライブラリOSSです。読みやすく、とても参考になります。
最近の公開されたものが特におすすめ
コンパイル結果 IL/JITアセンブラを確認する
速いコードはコンパイラの気持ちになることが大事。
ILViewer(Rider)
.NET デコンパイル結果のviewer
- Rider標準搭載
- ソースコードとILの対応を視覚的に確認可能
- マウスクリックで対応箇所をハイライト
- Low-Level/High-Level C#への逆コンパイルも可能
- Unity開発時はSolution Explorerからビルドする必要あり
dotPeek/AssemblyExplorer(Rider)
.NET デコンパイラー (.NETのdllやexeを読める)
- Riderに搭載(AssemblyExplorer)
- ILViewerを使えるので、Low-Level C#/High-Level C# /IL対応
ILSpy
オープンソースの .NET デコンパイラー
- BCLのC#/IL/JIT Asm(ReadyToRun)を簡単に確認可能
dnSpy
オープンソースの .NET デコンパイラー/デバッガー/Assembly editor
- BCLのC#/ILを簡単に確認可能
- デコンパイラとして機能面、見た目ではILSpyとほぼ同じ
- ブレークポイント、行ごとのステップ実行などデバッグ実行
- ローカル変数の確認
- プロセスへのアタッチ
- ILやC#を編集して実行
デバッグ機能やアセンブリの編集機能がついててすごい!
でも微妙に触り心地や細かい機能がILSpyと比べて行き届いてない感じがするので、上位互換ではない。
ILの手書きについての記事
SharpLab
ブラウザで使えるC#プレイグラウンド
- 実行、IL、JIT Asm、逆コンパイル、Syntax Tree表示
- 実行時の値のtrack
- MemoryのInspect
- Roslynブランチ指定、ランタイム指定(制限あり)
- Gist連携、URL共有機能
- 既知の問題:接続不安定、補完時のバグあり
Compiler Explorer
ブラウザで使える多言語Interactive Compiler
- 最新の.NETまで細かいRuntime指定
- IL/JIT Asm表示
- Outputから出力も表示
- top level statement非対応?
-
public static void Main(string[] args)
ならできる
LINQPad
スタンドアロン版のC#実行環境。
- 無償版でもIL/Asm表示可能
- 無償版でもローカルのdllの読み込みは可能
- Syntax Treeが見やすい
- データのVisualizeが得意(html)
-
注意:
#LINQPad optimize+
を付けないとDebugビルドになる - 有償版では補完、フォーマット、NuGet参照が可能 LINQPad - Purchase
お高めですが、買い切りなので悪くないと思います。(自分はまだ買ってません...)
RoslynPad
オープンソーススタンドアロン版のC#実行環境。
- IL表示可能
- NuGetが利用可能
- コード補完が使える
- .net frameworkから最新までローカルのruntimeを指定可能
roslynの力で補完が高速
C#までの逆コンパイルとJIT Asmが要らないならとてもよい。
Disasmo
.NETのJITコンパイラー開発者EgorBo氏作の VS2022 Add-in
- メソッドのクリックだけでJIT Asmを表示
- Run modeではPGOによる実行時のJIT Asmも確認可能
Riderでも使いたい...
DOTNET_JitDisasm
viewing-jit-dumps.md
JITアセンブラを出力する環境変数
- 関数を名前で指定(名前空間、class名、generics対応)
- 出力先の指定
- 基本的にJITのタイミングで出力
set DOTNET_JitDisasm=Program:Main
dotnet run
JitInpect
JIT Asmを確認できるライブラリ
- C#内でDelegate/MethodInfoからDisasm
- 再帰的に使われているメソッドもdisasm可能
- 対応ソースコードを表示可能
- Mac非対応
自薦ですが、実際使っているのでしょうがない。
現時点ではBenchmarkDotNetのDisassemblerを自分用に切り出したものです。
ガイドライン
.NET official Performance Guidelines
重要な原則:
- パフォーマンス改善は全体最適を目指す
- 特定シナリオのみの最適化で他を犠牲にしない
- 設計段階から考慮すべき
関連ドキュメント:
ベンチマーク
適切に測らなければ、何も意味がない。
BenchmarkDotNet
.NET標準のベンチマークフレームワーク
- 統計的に信頼性の高い測定
- 豊富な診断機能(メモリ割り当て、GCなど)
- JIT Asmも見られる(Mac非対応)
プロファイリング
最適化の鉄則:ボトルネックでなければ、最適化の優先度は低い。
dotTrace
JetBrains製のパフォーマンスプロファイラー
- Riderに標準付属
- サンプリング、トレーシング、タイムライン分析
- IDE(Rider/VisualStudio)統合
- Unity対応
パフォーマンスプロファイラーでは個人的に一番使いやすいです。
dotMemory
JetBrains製のメモリプロファイラー
- Riderに標準付属
- 型分析
- オブジェクトの依存関係分析
- 呼び出し元解析
- IDE(Rider/VisualStudio)統合
特に非同期関連はアロケーションがわかりづらいので、重宝しています。
ultra
.NET用詳細なプロファイラー
- Windows専用
- 他のプロファイラーよりもTimeLineが細かい
- https://profiler.firefox.com/を利用していてとても見やすい
- GC、JITの様子なども見やすい
- 共有可能
- 分析には時間がかかる
- IDE連携などがなく、ブラウザ利用なのでソースコードjumpがない
とにかく詳細に見たいときにおすすめ。
ETWを利用しているのでWindows限定なのが残念...
Intel VTune Profiler
Intel製の高性能CPU/GPU/FPGAプロファイラー
- Intel専用
- マイクロアーキテクチャレベルの詳細分析
- Source ↔ ASM
- ただし初回のjitしか見られないのでTiered Compilation off推奨
- ASMレベルでの時間計測
- 実はUnity対応しているらしい
- 注意 administrator で実行
- JitInspect(PrintInstructionAddresses=true)と組み合わせての関数名の確認がおすすめ
- FlameGraphはcollect stacksをonにする必要あり
この記事を書くにあたって初めて触りましたが、すごいですね。でもIntel専用...
Application欄はただのコマンドなのでdotnet
でもexe直接でも大丈夫です。
.NET diagnostic CLI tools
.NET用CLIツール群
- dotnet-traceはCLIから使えるプロファイラー
- (出力される.nettrace fileはdotTraceでも開ける)
- dotnet-stackは無限ループしているときなどに簡単にスタックが見られて便利
他にもいろいろありますが、たまに使ったりであまり活用できていません。
PerfView
ほぼWindow専用のパフォーマンス分析ツール
- Windowsのkernelまで含めた詳細な情報が分析が可能
- Advancedでは同じ関数でもJIT(QuickJIT、Tier1など)毎にも確認可
- 時間のかかっている呼び出し元のソースコードに飛ぶことなども可能
- あまりUI/UXがよくない
自分もあまり活用できていません。
コミュニティ
話す場所があるって大事。
C# Japan (Discord)
日本語でC#について話せるコミュニティ。
- 最新情報の共有や質問が可能
- ++C++の岩永氏が立ち上げ
C# (Discord)
英語の大規模C#コミュニティ。
- コンパイラ、ゲーム、ランタイムなど様々なカテゴリ
- かなり活発
-
#allow-unsafe-blocks
チャンネルでは日々高度な最適化の話題が議論される- EgorBo氏などJIT開発者も活発に参加
Discussion