概要
- ZLinqは 構造体 と ジェネリクス に基づき、 ゼロアロケーション を実現した革新的なLINQライブラリです。
- .NET 10の全メソッド を100%カバーし、 SIMD最適化 や複数プラットフォーム対応を提供します。
- パフォーマンス と アセンブリ肥大化回避 を両立し、既存のLINQ実装の課題を解決しました。
- Drop-In Replacement Source Generator や テスト互換性 も確保し、既存コードの置き換えも容易です。
- 詳細な最適化設計 やアーキテクチャの工夫についても解説します。
ZLinq v1リリースとその特徴
- ZLinq v1 は、構造体・ジェネリクス活用により ゼロアロケーション を実現することに成功したLINQライブラリであることを発表
- LINQ to Span, LINQ to SIMD, LINQ to Tree (FileSystem, JSON, GameObject等)などの拡張を提供すること
- Source GeneratorによるDrop-In Replacement 機能や、.NET Standard 2.0, Unity, Godotなど 複数プラットフォーム への対応を実現
- GitHubで 2000スター超 を獲得するなど、注目を集めていることを報告
- 詳細は公式リポジトリ(https://github.com/Cysharp/ZLinq)で確認すること
過去のLINQ実装の課題とZLinqの優位性
- 構造体ベースのLINQは過去にも存在したが、 実用的なものはなかった ことを指摘
- アセンブリサイズの肥大化
- オペレータカバレッジ不足
- 最適化不足によるパフォーマンス問題
- ZLinqは .NET 10の全メソッド・オーバーロードを100%カバー し、 99%の動作互換 を実現
- SIMD最適化 や アロケーション削減以外の最適化 も実装し、多くのケースで標準LINQを上回る性能を達成すること
- 開発者の豊富なLINQ実装経験(linq.js, UniRx, R3, SimdLinq等)や高速シリアライザ(MessagePack-CSharp, MemoryPack等)知見を融合していること
パフォーマンスとベンチマーク
- 通常のLINQはメソッドチェーンが増えると アロケーションが増加 するが、ZLinqは 常にゼロアロケーション を維持
- ベンチマークシナリオをGitHub Actionsで公開し、多くの実用ケースでZLinqが優位であることを検証
- Selectの多重呼び出し や Distinct/OrderBy等の中間バッファ必須操作 で特に大きな差を実証
- .NET 9の演算子チェーン最適化 も全て実装し、 全世代の.NET で最新最適化を享受可能
- AsValueEnumerable() を追加するだけで既存コードをZLinq化できる利便性
- System.Linq.Tests を移植し、9000件のテストで動作互換性を保証
Drop-In Replacement Source Generator
- Drop-In Replacement Source Generator により、 AsValueEnumerable()さえ不要 でZLinqへの置き換えが可能
- 置き換え範囲の制御も柔軟に行えること
- テストコードも変更なしでZLinqに切り替えられる運用性
ValueEnumerableアーキテクチャと最適化
- ValueEnumerable<T> は、 ref struct によるチェーンを可能にし、 IValueEnumerator<T> インターフェースを基盤とする設計
- 型推論の制約を回避するため、 型宣言で型を明示 し、アセンブリ肥大化を防止
- TryGetNext(out T current) 方式を採用し、 MoveNext + Current の2メソッド呼び出しを 1回に集約 して高速化
- 構造体サイズの増大 を最小化し、チェーン時のコピーコストを抑制
- 共変・反変非対応 だが、Span<T>との互換性や安全性を優先
TryGetNextの詳細
- IEnumerator<T> はMoveNext()とCurrentの2操作が必要だが、ZLinqは TryGetNext で1回の呼び出しに集約
- Rustのイテレータ設計も参考にした設計思想
- Select実装 比較で、ZLinqは「current」フィールド不要で構造体サイズを縮小
- 構造体チェーン が深くなってもパフォーマンスを維持
共変・反変の非対応について
- 共変・反変 はSpan<T>と非互換であり、現代.NETでは 安全性の観点から非推奨
- 例:配列のSpan変換でランタイムエラー発生リスク
- ZLinqは 安全性とパフォーマンス を優先し、これらの機能を割り切っていること
TryGetNonEnumeratedCount, TryGetSpan, TryCopyToの最適化
- TryGetNonEnumeratedCount :元ソースが確定サイズかつフィルタなしの場合、ToArray等で 固定長配列確保 が可能
- TryGetSpan :連続メモリアクセス可能な場合、 SIMDやSpanベース高速処理 が実現
- TryCopyTo :内部イテレータによる パフォーマンス向上 を実現
- 外部イテレータと内部イテレータ の違いを活かした最適化設計
このように、ZLinqは 構造体ベースLINQの集大成 として、 パフォーマンス・安全性・実用性・互換性 を高次元で融合した次世代LINQライブラリであることを強調することができます。