LINQ Ring : 대규모 컬렉션에 대한 Any () 대 Contains ()


103

방대한 개체 컬렉션을 감안할 때 다음간에 성능 차이가 있습니까?

컬렉션 포함 :

myCollection.Contains(myElement)

Enumerable.Any :

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

7
10'000.000 int의 모음. 승자는 300 % 포함입니다. 그러나 아래에 언급 된 차이를 고려할 가치가 있습니다.
SDReyes 2010

답변:


143

Contains()인스턴스 메서드이며 성능은 컬렉션 자체에 크게 좌우됩니다. 예를 들어, Contains()a List는 O (n)이고, Contains()a HashSet는 O (1)입니다.

Any()확장 메서드이며 컬렉션을 통해 모든 개체에 대리자를 적용합니다. 따라서 복잡도는 O (n)입니다.

Any()델리게이트를 전달할 수 있기 때문에 더 유연합니다. Contains()개체 만받을 수 있습니다.


27
ContainsIEnumerable<T>(일부 컬렉션에는 자체 Contains인스턴스 메서드도 있지만) 에 대한 확장 메서드이기도합니다 . 말했듯이, AnyContains사용자 지정 조건 자를 전달할 수 있기 때문에 보다 유연 하지만 각 요소에 대해 대리자 호출을 수행 할 필요가 없기 때문에 약간 더 빠를 Contains 있습니다.
LukeH 2010

1
Any () 는 컬렉션의 모든 객체에 대해 작업을 수행 합니까 아니면 첫 번째 일치로 종료합니까?
Quarkly

1
적어도 소스 에 따르면 첫 번째 일치에서 중지됩니다. All()유사하게 작동합니다.
Etienne de Martel

13

컬렉션에 따라 다릅니다. 정렬 된 컬렉션 Contains이있는 경우 스마트 검색 (이진, 해시, b- 트리 등)을 수행 할 수 있지만`Any ()를 사용하면 기본적으로 찾을 때까지 열거 (LINQ-to-Objects 가정)해야합니다. .

또한 귀하의 예에서 참조 평등을 확인 Any()하는 ==연산자를 사용하고 있으며 재정의 될 수있는 또는 메서드를 Contains사용 IEquatable<T>합니다 Equals().


4
.Any를 사용하면 속성을 쉽게 비교할 수 있습니다. .Contains를 사용하면 개체를 비교할 수 있으며 속성을 비교하려면 추가 IEqualityComparer가 필요합니다.
msfanboy

1
@msfanboy : 사실이지만 질문은 특히 성능에 관한 것이었고 전체 개체를 비교하는 것으로 나타났습니다. 그래서 여기서는 관련이 없다고 생각합니다.
tster

4

나는 그것이 구현 myCollection방법을 지시하는 유형에 달려 있다고 생각합니다 Contains(). 예를 들어 정렬 된 이진 트리의 경우 더 스마트하게 검색 할 수 있습니다. 또한 요소의 해시를 고려할 수 있습니다. Any()반면에 조건을 만족하는 첫 번째 요소를 찾을 때까지 컬렉션을 통해 열거됩니다. 객체에 더 스마트 한 검색 방법이 있는지에 대한 최적화는 없습니다.


0

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)을 반복합니다.

이것이 효과가 있기를 바랍니다 ....

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.