【要約】.NET で巨大なマネージド配列を作ってみた [Qiita_Trend] | Summary by TechDistill
> Source: Qiita_Trend
Execute Primary Source
// Problem
大規模なデータセットを扱う.NET開発者が、配列のインデックス上限という制約に直面している。従来の回避策には、以下の課題が存在する。
- ・非マネージドメモリの利用: 手動のメモリ管理が必要であり、stringやobjectなどの参照型を扱えない。
- ・ジャグ配列の利用: メモリが不連続であり、セグメント境界を跨ぐアクセスの実装が複雑になる。
- ・ランタイムの制限: 64ビット環境であっても、標準の配列はint型のインデックスに縛られる。
// Approach
著者は、InlineArrayAttributeを用いて、一つの物理配列要素に複数の論理要素を格納する「チャンク方式」を採用した。
- ・チャンク構造の構築: 要素サイズに基づき、最適なチャンク長を持つ構造体を定義する。
- ・型の合成による効率化: 素数を用いたチャンクの組み合わせにより、最小限の型定義で任意のチャンク長を表現する。
- ・型ロード問題の回避: 実行時に適切な型を割り当てるため、ラムダとNoInliningを用いて型ロードを遅延させる。
- ・高速アクセスの実現: Unsafe.Addを活用し、論理インデックスから直接参照を取得する設計とする。
// Result
64ビット環境において、理論上128TiB(byte型の場合)に及ぶ巨大な連続マネージド配列の表現を可能にした。
- ・APIの提供: BigArray<T>, BigSpan<T>, BigMemory<T> を実装した。
- ・開発体験の維持: 既存のSpan/Memoryと同様の操作感を実現した。
- ・安全性と性能の両立: GCによる参照追跡を維持しつつ、境界チェックを最小限に抑えた高速アクセスを提供した。
Senior Engineer Insight
> ランタイムの制約を言語機能で巧みに回避した、極めて実践的な実装である。特に、型ロード制限を回避するための遅延割り当て戦略は、JITの挙動を深く理解した高度な知見と言える。ただし、巨大なマネージド配列はGCの走査対象となり、STW時間を増大させるリスクがある。大規模トラフィックを扱う現場では、メモリ確保の容易さだけでなく、GC負荷とレイテンシのトレードオフを厳格に評価すべきだ。