2013-05-20 1 views
2

5000 + 항목이 포함 된 일반 콜렉션이 있습니다. 모든 항목은 고유하므로 컬렉션에서 항목을 가져 오는 데 SingleOrDefault를 사용했습니다. 오늘 Red Gate ANTS 프로파일 러를 사용하여 코드를 조사한 결과, SingleOrDefault 호출이 (~ 3.5 초) 5000 반복에 대해 1800 만 건이 발생했음을 알았습니다. 반면 FirstOrDefault로 변경하면 9 백만 건 (~ 1.5 초)이 걸립니다.ANSI 프로파일 러를 보는 동안 FirstOrDefault가 SingleOrDefault보다 훨씬 빠릅니다.

컬렉션의 모든 항목이 고유하다는 것을 알고 있기 때문에 SingleOrDefault를 사용했습니다.

편집 : 우리가 SingleOrDefault를 사용해야하는 정확한 시나리오 임에도 불구하고 질문이 왜 FirstOrDefault가 SingleOrDefault보다 빠를 것입니까?

+3

질문이 있습니까? – cadrell0

+1

요소가 고유하다는 것을 * 이미 * 알고 있다면,'SingleOrDefault'에 의해 수행 된 추가 작업은 불필요합니다. –

답변

3

SingleOrDefault(predicate)은 지정된 조건부와 일치하는 항목이 하나 이상이어야하므로 컬렉션의 시작 부분에서 일치하는 항목을 찾더라도 IEnumerable의 끝까지 계속해야합니다.

FirstOrDefault(predicate)은 컬렉션에서 일치하는 항목을 찾으면 즉시 중지합니다. "첫 경기"가 IEnumerable 전체에 균등하게 분포되어있는 경우 평균적으로 IEnumerable의 절반을 통과해야합니다. N 항목의 순서에 대한

SingleOrDefault은 술어를 N 번 실행되며, FirstOrDefault은 (평균) N/2 시간을 당신의 술어를 실행합니다. 이는 SingleOrDefaultFirstOrDefault의 두 배 "히트"를 보았던 이유를 설명합니다.

을 알고있는 경우 컬렉션 소스가 나와 내 시스템에 의해 제어되기 때문에 일치하는 항목이 하나만있는 경우 FirstOrDefault을 사용하는 것이 더 나을 것입니다. 예를 들어 컬렉션이 사용자로부터 온 것이라면 사용자의 입력을 확인하기 위해 SingleOrDefault을 사용하는 것이 좋습니다.

6

SingleOrDefault()은 예외가 하나 이상있는 경우 발생합니다. 그것을 결정하기 위해서는 하나 이상 존재하지 않는지 확인해야합니다.

반면에 FirstOrDefault()은 발견되면 다시 볼 수 없게됩니다. 따라서 많은 경우에 상당히 빨라질 것으로 기대됩니다.

+0

그냥이 답변에 추가하려면 : 값이 사실 고유해야만 할 때'Single (OrDefault) (...)'를 사용해야합니다. 그렇지 않으면'First (OrDefault) (...)'가 더 빠릅니다. – Tory

1

FirstOrDefault는 첫 번째 히트시 돌아갑니다. SinglerOrDefault는 첫 번째 히트시 돌아 오지 않지만 다른 모든 요소를 ​​검사하여 고유한지 확인합니다. 따라서 FirstOrDefault는 대부분의 경우 더 빠릅니다. Ido 당신은 유일성 검사가 FirstOrDefault를 취할 필요가 없습니다.

1

SingleOrDefault 또는 FirstOrDefault 중 하나의 병목 현상이 매우 심각하게 의심됩니다. 나는 프로파일 링 도구가 튀김에 훨씬 더 큰 물고기를 강조 할 것을 희망한다. 사용자 자신의 메트릭은 주어진 반복에 대해 거의 식별 할 수없는 단위 시간에 해당 함을 나타냅니다.

그러나 에 맞는과 일치하는 것을 사용하는 것이 좋습니다. 즉, 술어 과 일치하는 오류가 두 개 이상 있는데? 그렇다면, 그 기대를 시행하는 방법을 사용하십시오. SingleOrDefault. (마찬가지로 이없는 경우도 오류입니다. Single을 사용하십시오. 둘 이상의 오류가 없으면 대신 First 변형을 사용해보십시오.

다른 답변이 논의하는 것처럼 이제는 어느 쪽이 다른 쪽보다 약간 더 빨라질 수 있는지 분명해야합니다. 하나는 제약 조건을 적용하는 것이며, 물론 이것은 논리를 실행함으로써 성취됩니다. 다른 하나는 특정 제약 조건을 시행하지 않으므로 제약 조건에 의해 지연되지 않습니다.

0

나는 Single 및 SingleOrDefault를 사용하는 쿼리가 First 또는 FirstOrDefault를 사용하는 쿼리보다 빠르다는 것을 나타내는 LinqPad를 사용하여 테스트를 실행했습니다. 이 테스트는 대규모 데이터 세트에 대한 단순한 쿼리 (조인이 필요 없음)에서 수행되었습니다. 저는 이것이 결과라고 기대하지 않았습니다. 사실 First와 FirstOrDefault를 사용해야한다는 것을 다른 개발자에게 증명하려고 시도 했었지만, 증명이 Single이 실제로 빨랐다는 사실이 밝혀지면서 필자의 주장에 대한 나의 토대가 사라졌습니다. First가 더 빠르지 만 담요 케이스라고 가정하지 않는 경우가 있습니다.

관련 문제