---
title: ふとしたことから始めたNET ランタイムへのコントリビュート
tags: 
author: [prozolic（プロゾリック）](https://image.docswell.com/user/prozolic)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/VJPKLLDNE8.jpg?width=480
description: 2026年9月19日に開催されたC# Kaigi 2026の登壇資料になります。
published: September 19, 26
canonical: https://image.docswell.com/s/prozolic/KGNV4N-2026-09-19-230203
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/VJPKLLDNE8.jpg)

ふとしたことから始めた
.NET ランタイムへのコントリビュート
C# Kaigi 2026
2026/09/19 （土）
prozolic


# Page. 2

![Page Image](https://bcdn.docswell.com/page/2EVVQQ1YEQ.jpg)

自己紹介
prozolic（プロゾリック）
業務アプリケーションエンジニア/一般C#er
GitHub： @prozolic
最近の趣味： ウォーキング
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/57GLWW2WEL.jpg)

内容
.NET ランタイムへのコントリビュートを始めたきっかけ
コントリビュートする上で、どこからはじめたか、どんなことをしたか
作成した/使用したツールについて
※個人的な目線での内容も含まれています。
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/4EQY33PQJP.jpg)

コントリビュートするきっかけ
自作のOSS開発以外に、大規模のOSS開発へ貢献に興味があった。
じんぐるさん（@xin9le）の.NET 9でのパフォーマンス改善の貢献が書かれたブログ [1]
を読んで、私もやってみようと決意！
この時に.NET ランタイムが、オープンソースであったことを再認識
[1] https://www.sigmact.com/updated/dotnet/net9-perf-pr/
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/KJ4W11YY71.jpg)

.NET ランタイム
dotnet/runtimeは、大きく分けて、三つのカテゴリに分類される。
私は、Libraries と CoreLib(C#) で貢献を開始しました。
Libraries
メインライブラリ
CoreLib
低レベルコアライブラリ（組み込み型など）
Runtime
実行エンジン（JITコンパイラ/GCなど）
C#
C#、C/C++
C/C++
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/LE1YGG6N7G.jpg)

何から始めたらいいのか？
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/GEWGKK4MJ2.jpg)

とりあえず、環境準備
ビルド/デバッグ環境をまず準備するところから始めました。
手順は、dotnet/runtimeのWorkflow Guideに基本的に全て書いてあります。
だけど失敗するので、これがある意味一番大変。
失敗例
ビルドがたまに失敗する
デバッグができない
主にキャッシュが原因。今もバージョン更新時に発生
デバッグビルドを忘れていた
環境固有の問題が出る
Windows + 日本語環境で失敗することがあった
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/47ZLZZ2MJ3.jpg)

貢献方法
プルリクエスト
新規機能追加
パフォーマンス改善
まずは、ここから始める
不具合修正
typo 修正
バグレポート報告
API提案
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/YJ6WZZV5JV.jpg)

私が行った進め方
最初は見る領域を狭くする。
自分が使ったことのあるものから見る。
過去使われた既知パターンを調べて、適用できるか確認する。
過去のマージされたパフォーマンス関連のPRを読む。
見る領域を徐々に広げていく。
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/GJ5MWWDGJ4.jpg)

どこから始めるか
そもそも当たり前ですが、領域自体が多い。
とりあえず、 System.Collections.Immutable を選びました。
理由は、当時OSSの実装で ImmutableArray を使っていたからという軽い理由
これでもまだライブラリの一部
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/9E29QQ8D7R.jpg)

パフォーマンス改善
パフォーマンス改善（高速化、アロケーション削減など）自体は、現在進行形でどの領域でも
活発に行われている。
コンパイラレベルで対応する。
既存のアルゴリズム実装を別の実装に切り換える。
新しいAPIに切り換える。
過去に行われた手法を別の場所で使う。
まずは過去のPRからどんなことをしているのか確認から始める。
並行してソースコードも読みつつ。
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/D7Y4WW6MEM.jpg)

既知の最適化パターンを使う
ということで見つけたのが、 ImmutableArrayExtensions.SequenceEqual の高速化
最適化パスの追加（コレクションやLINQなどで昔から使われている方法）
public static bool SequenceEqual&lt;TDerived, TBase&gt;(
this ImmutableArray&lt;TBase&gt; immutableArray,
IEnumerable&lt;TDerived&gt; items,
IEqualityComparer&lt;TBase&gt;? comparer = null)
{
ICollection&lt;T&gt;であれば、LINQを
if (items is ICollection&lt;TBase&gt; itemsCol)
{
実行する
immutableArray.ThrowNullRefIfNotInitialized();
return Enumerable.SequenceEqual(immutableArray.array, itemsCol, comparer);
}
return Enumerate(immutableArray, items, comparer);
もともとはforループで一つ一つ判定
}
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/VENY99Z3J8.jpg)

既知の最適化パターンを使う ベンチマーク
これだけでも高速化する
最適化パス以外もほぼ変わらない
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/Y79P22ZPE3.jpg)

レビュー過程で実装変更
一番最初の提案した実装は、 ImmutableArray の内部で使われている別のロジックを使用
レビューワから「 Enumerable.SequenceEqual を使うのが最速」とアドバイス
ベンチマークから Enumerable.SequenceEqual + 既存実装の形で落ち着く
途中で dotnet/performance にベンチマーク追加PRも行うサブイベントも発生
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/G78D551X7D.jpg)

色々なケースでベンチマークを計測
ベンチマーク結果が無いとどれくらい良くなったのか分からない。
また良く使われるケースで回帰していないか確認できるようにする必要がある。
大容量だと速くなるが、小規模だと遅くなるなどは、APIによってはだめ。
私も結構これと同じことをして、PRしなかったものもありました。
そのため、パフォーマンス改善では、ベンチマーク結果とベンチマークで使ったソースも載せ
ることが大事（当たり前）
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/L7LMYYQNJR.jpg)

別の部分でも使えないか確認
あとは別の部分でも同じような形が使えないかソースコードをチェックする。
実際に、 string.Concat でも最適化パスを追加するなど行いました。
ただし、最適化パスを追加すると分岐処理が追加され、わずかにオーバーヘッドも入るため、
なんでもかんでも入れると遅くなる。
オーバーヘッドとのトレードオフに注意する必要がある。
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4EMYNN1QEW.jpg)

不具合の見つけ方（一例）
前提として、基本的な使い方でバグが起きることはあまりないです。
私個人としては、ほとんど遭遇しない（稀に遭遇する）
System.Collections.Immutable では、異常値を入力するとバグが発生しそうなコードがあ
りました。
そこで色々なケースを入力してみることに。
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/PER9DDLKJ9.jpg)

バグ発見
結構見つかりました...
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/P7XQ11W5EX.jpg)

オーバーフローによる上限/下限チェックのすり抜け
List&lt;T&gt; などの主要コレクションは行われているチェックとは異なっていることが原因。
一部ケースはすでにバグ報告されていたが、まだ未対応だった。
修正前
修正後（uintキャストの追加）
Requires.Range(
count &gt;= 0 &amp;&amp;
startIndex + count &lt;= this.Count,
nameof(count));
Requires.Range(
count &gt;= 0 &amp;&amp;
(uint)(startIndex + count) &lt;= (uint)this.Count,
nameof(count))
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/37K922VR7D.jpg)

その他にもコード最適化も行ったり
throw 句をヘルパーメソッドに変更する、いわゆるインライン化しやすくなる対応。
throw 句が存在するとコンパイラがインライン対象外と判定される。
同様の対応が過去にも複数で行われていたので、これも既知のパターン。
変更前
変更後
public static T First&lt;T&gt;(
this ImmutableArray&lt;T&gt;.Builder builder)
{
Requires.NotNull(builder, nameof(builder));
public static T First&lt;T&gt;(
this ImmutableArray&lt;T&gt;.Builder builder)
{
Requires.NotNull(builder, nameof(builder));
}
if (!builder.Any())
{
throw new InvalidOperationException();
}
if (!builder.Any())
{
ThrowHelper.ThrowInvalidOperationException();
}
return builder[0];
return builder[0];
}
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/LJ3W44MGJ5.jpg)

継続して進めるために
他の領域でも適用できないか、同じバグがないかという視点で、他の領域のソースコードを
読む。
新しい領域の構造や内部ロジックなどの知識を獲得できる。
string.IndexOf ( StringComparison.OrdinalIgnoreCase )のようなコア部分でも、同
じようなバグを見つけることもありました。
たまに自作のOSSへ反映するなどメリットがある。
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/8JDKQQ6NEG.jpg)

そして深く把握すること
ただし、さらに深淵を知るにはもっと知識が必要。
領域ごとに使う知識も必要になり、複雑な動きやソースコードだけでよくわからない部
分もたくさんある。
ひたすらデバッグしたり、AI エージェントツールを使って理解を深めることが大事。
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/VEPKLLYN78.jpg)

最新の状況を
どうやって追いかけるのか？
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/27VVQQGY7Q.jpg)

作ったツール PR Digest.NET
マージされた最新のプルリクエストの概要をAIで日本語要約するサイト
英語が苦手で、PRの内容を把握しやすくするために作成
24
https://prozolic.github.io/PRDigest.NET


# Page. 25

![Page Image](https://bcdn.docswell.com/page/5JGLWW8W7L.jpg)

作ったツール PR Digest.NET
指定のラベルが適用されているプルリクエストなども確認できる。
どの領域がよくマージされているかなどを把握できる。
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/47QY339QEP.jpg)

よく使うツール/環境変数
ILSpy
最新機能で生成されるコードや最新SDKでビルドしたコードを確認する際に使用。
DOTNET_JitDisasm 環境変数
プログラムの逆アセンブラ（disassembler）
メソッド単位がどのように展開されるなど、パフォーマンス分析時に使う。
最近はAIエージェント経由で、出力結果を確認することが多い。
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/KE4W11XYJ1.jpg)

まとめ
ふとしたことで始めた .NET ランタイムの貢献は色々大変。
それでも少しずつ進めていくことが大事。
他のPRの内容についても、ツールなど用いて日々把握していくことが大事。
.NET ランタイムは面白い。
27


