オブジェクトの膨大なコレクションがある場合、次の間にパフォーマンスの違いはありますか?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
オブジェクトの膨大なコレクションがある場合、次の間にパフォーマンスの違いはありますか?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
回答:
Contains()
インスタンスメソッドであり、そのパフォーマンスはコレクション自体に大きく依存します。たとえば、Contains()
a List
はO(n)、Contains()
a HashSet
はO(1)です。
Any()
は拡張メソッドであり、すべてのオブジェクトにデリゲートを適用して、コレクションを単純に処理します。したがって、O(n)の複雑さを持ちます。
Any()
ただし、デリゲートを渡すことができるため、より柔軟です。Contains()
オブジェクトのみを受け入れることができます。
Contains
に対する拡張メソッドでもありますIEnumerable<T>
(ただし、一部のコレクションには独自のContains
インスタンスメソッドもあります)。あなたが言うように、カスタム述語を渡すことができるためAny
よりも柔軟性Contains
がContains
ありますが、各要素に対してデリゲート呼び出しを実行する必要がないため、わずかに高速かもしれません。
コレクションによって異なります。順序付けられたコレクションがある場合Contains
は、スマート検索(バイナリ、ハッシュ、bツリーなど)を実行できますが、 `Any()を使用すると、基本的に、それが見つかるまで列挙し続けます(LINQ-to-Objectsを想定)。 。
また、例でAny()
は==
、参照の等価性をチェックする演算子を使用しているのに対し、オーバーライドされる可能性のあるまたはメソッドContains
を使用していることにも注意してください。IEquatable<T>
Equals()
Contains()も、正しい方法で使用すると高速に動作する拡張メソッドです。例:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
これはクエリを与えます
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
一方、Any()は常にO(n)を反復処理します。
これがうまくいくことを願っています...