2009-06-05 2 views
1

다음 Lambda와 Linq 표현식은 실행 경로 측면에서 동일합니까? Linq가 다르게 실행하려고하는지 궁금하네요. IEnumerable을 생성하기 전에 IEnumerable을 생성하기 때문입니다. lambda 표현식이 발견 된 첫 번째 숫자에서 멈추지 만, 열거 형에 아무 것도 없는지를 결정해야합니다.다음과 같은 Lambda와 Linq 표현식은 동일합니까?

var x = valueToMatch 
    .Any(c => Char.IsDigit(c)); 

var y = (from c in valueToMatch 
     select c).Any(c => Char.IsDigit(c)); here 

Thx! 조엘

답변

3

달리 실행되지만 상당한 방식으로 실행되지는 않습니다. MSIL Disassembler을 사용하면 최적화가 켜져 있어도 첫 번째 표현과 두 번째 표현에 대해 약간 다른 출력이 표시됩니다. Reflector을 사용하여 볼 수도 있습니다 (조금 더 읽기 쉽습니다). 는 상관 (c => Char.IsDigit (c)) 식을 실행하기 전에

[CompilerGenerated] 
private static char <Match2>b__2(char c) 
{ 
    return c; 
} 

:

번째 버전은 기본적으로 같은 각 요소를 통과 할 것이다. 그래서 실제로 차이가 있습니다.

그러나 차이점은 매우 작다고 생각합니다. 두 번째 메서드는 ~ 185ms 걸리는 반면 첫 번째 메서드는 ~ 125ms 내에서 각 메서드를 사용하여 10,000,000 이상 반복되는 10,000 문자 목록을 테스트합니다. 쿼리 표현식

+1

LINQPad를 사용하여 IL을 볼 수도 있습니다 . IMHO "from value in Catch from c"는이 경우에 매우 중복 됨 – dplante

+0

실제로, 나는 그것이 적어도 "나를 어떻게 생각 하는가?"라고 생각했습니다. – rmoore

1

대략적으로 같습니다. 컴파일러는 아마도 select를 최적화 할 것이고 두 가지는 100 % 동일 할 것입니다. anyrate에서는 Linq가 지연 평가되므로 valueToMatch는 두 경우 모두 정확히 같은 수를 열거합니다.

+2

컴파일러는 select를 최적화하지 않으며, 그럴만한 이유가 있습니다. 주제에 대한 내 기사를 참조하십시오. http://blogs.msdn.com/ericlippert/archive/2008/05/12/trivial-projections-are-usually-optimized-away.aspx –

0

, 이것은 identity function 나타낸다 :이 식의 결과가 입력 matchToValue 정확하게 동일 의미

from c in valueToMatch select c 

. 따라서 제공 한 예제는 의미 상 동등합니다. 같은 비 식별 선택의 경우

:

from c in valueToMatch select c + ";" 

IEnumerable<char>는 열거 때 valueToMatch의 컨텐츠를 소비하고 변경되는, 생성된다.

이 호출 : 그것은 일치하는 항목을 찾을 때까지

(from c in valueToMatch select c + ";").Any(c => Char.IsDigit(c)) 

은 내부 쿼리를 열거합니다. 보시다시피 소스 쿼리와 상관없이 Any을 호출 할 때까지 실행되지 않습니다. IEnumerable<char> 인스턴스는 이미 실행 된 쿼리가 아니라 쿼리를 실행할 수있는 기능을 나타냅니다. 이 개념은 deferred execution으로 알려져 있습니다.

관련 문제