web-dev-qa-db-ja.com

LINQリング:巨大なコレクションのAny()vs Contains()

オブジェクトの膨大なコレクションがある場合、次の間にパフォーマンスの違いはありますか?

Collection.Contains

myCollection.Contains(myElement)

Enumerable.Any

myCollection.Any(currentElement => currentElement == myElement)
95
SDReyes

Contains()はインスタンスメソッドであり、そのパフォーマンスはコレクション自体に大きく依存します。たとえば、リストのContains()はO(n)ですが、HashSetのContains()はO(1)です。

Any()は拡張メソッドであり、すべてのオブジェクトにデリゲートを適用して、コレクションを単純に調べます。したがって、O(n)の複雑さがあります。

ただし、Any()はデリゲートを渡すことができるため、より柔軟です。 Contains()はオブジェクトのみを受け入れることができます。

128

コレクションに依存します。順序付けられたコレクションがある場合、Containsはスマート検索(バイナリ、ハッシュ、bツリーなど)を実行しますが、Any()を使用すると、それが見つかるまで列挙に追われます(LINQ to Objectsと仮定)

また、例ではAny()が参照の等価性をチェックする「==」演算子を使用しているのに対し、ContainsはIEquitableまたはオーバーライドされる可能性のあるEquals()メソッドを使用していることに注意してください。

12
tster

myCollectionのタイプに依存すると思いますが、これはContains()の実装方法を決定します。たとえば、ソートされたバイナリツリーであれば、よりスマートに検索できます。また、要素のハッシュを考慮する場合があります。一方、Any()は、条件を満たす最初の要素が見つかるまでコレクションを列挙します。オブジェクトにもっとスマートな検索方法があるかどうかについての最適化はありません。

4
Jeff Mercado