独自のLINQ&の実装IEnumerable< T> [閉まっている]
-
22-07-2019 - |
質問
私が取り組んでいるプロジェクトには、非常に大きなコレクション(1M-1B要素)があり、ほとんどがコレクションとして変更されています。
リアルタイムアプリであるため、パフォーマンスが最も重要です。
Reverse、BinarySearch(可能な?)などの一部の操作では、Selectなどのその他の操作よりも負荷が大きくなります。
MoveNext、MovePrevなどを使用して独自のIEnumerableを実装し、これらを利用する独自の実装LINQ拡張機能を実装することは可能ですか?
これが発生する場合は、プロジェクトの終了時に発生します。最初に動作させる必要があるため、それから高速化します。
これらすべてのことは、あまり手間がかからないでしょう?
解決
いくつかの状況を特別なケースとする Enumerable
の独自の実装を作成することは非常に確実です。基本的に、独自のコレクションタイプ(または List< T>
などのコレクションのみ)を検出し、必要に応じてより効率的な実装を使用する必要があります。
サンプルプロジェクトを使用して、LINQ to Objects in時間"例を見てみたいと思うかもしれません。完全な実装ではありません。特に、実際のLINQ to Objectsよりも効率的ではありませんが ですが、それでもおもしろいかもしれません。
別の方法として、 i4o(インデックス付きLINQ)がすぐに必要なすべての処理を実行することがあります。または、ゼロから始めるよりも貢献した方が良いでしょう。チェックアウトに値する。
1日の終わりには、LINQは基本的に構文糖と相まって素晴らしいデザインであることを忘れないでください。 C#コンパイラは、たとえば System.Linq.Enumerable
について特別な何かを知りません。
他のヒント
パフォーマンスが本当に必要な場合は、多くのことができます。次の選択を忘れないでください:
var result = from element in collection
where element.Id == id
select element;
コンパイル:
var result = collection.Where(element => element.Id == id);
collection
のタイプに対して次のメソッドを作成すると、プライマリアクションがIdメンバーと同等であるという事実を活用し、最適化された方法でリクエストを処理できます。重要なのは、コレクションでパフォーマンスが重要な操作を正しく識別し、それらを実行するための正しいアルゴリズム(つまり複雑さ)を選択することです。
public IEnumerable<TElement> Where(Expression<Func<TElement, bool>> selector)
{
// detect equality of the Id member and return some special value
}
Consider System.Linq.Enumerable.Reverse()-このメソッドは、最初の結果を返す前にIEnumerableを完全に列挙します。
クエリがmyCollection.Reverse()。Take(10)であり、コレクションに数十億のアイテムがある場合、10を取得するために数十億のアイテムを列挙するのは恐ろしい考えです。
独自のタイプでReverseメソッドを提供した場合、コレクションを逆方向にループするだけのより優れた実装を提供できます(場合によってはインデックスによって)。
これの鍵は、実装を制御する独自のタイプを提供することです。すべての IEnumerable&lt; T&gt;
で機能する実装を使用することはできません。これらの実装では、カスタムコレクションタイプの機能を十分に活用できないためです。
自分で実装することは可能ですか? MoveNextの可能性があるIEnumerable、 MovePrevなど、および独自に実装されたLINQ を活用する拡張機能 これら?
IEnumerable
(より正確には、 IEnumerator
)には MovePrev
がありません。インターフェイスを定義できます:
public interface IReversable<T> : IEnumerable<T>
{
IEnumerator<T> GetReverseEnumerator();
}
これは、効率的な逆列挙をサポートする任意のコンテナで実装できます。
その後、 Reverse
(拡張メソッド)のオーバーロードを記述して、この新しいインターフェイスやインターフェイスを実装するコレクションクラスなどを処理できます。そして、それらのコレクションを使用する必要があります。 List&lt; T&gt;
のような標準クラスの代わりにクラス。
しかし(チェックするのに便利なReflectorはありません)組み込みの Reverse
は、 IList
コレクションのインターフェイス。これにより、最も一般的なケースが最適化されます。
したがって、この種のアプローチにはあまり意味がありません。