2009-09-04 11 views
2

각 루프에 대해를 사용하는 대신 LINQ를 사용하는 성능에 대해 공정한 조언을 읽었으며 LINQ 쿼리를 사용하여 이해하는 것이 조금 느리지 만 일반적으로 편의성과 표현력이 필요합니다. 그러나 for 루프에서 쿼리의 결과를 사용하는 것이 얼마나 느린지 조금 혼란 스럽습니다.이 쿼리에 LINQ를 사용해야합니까?

'위치'라는 집합과 '항목'이라는 개체 집합이 있다고 가정 해 보겠습니다. 각 '항목'은 하나의 '위치'에만 속할 수 있습니다. 같은 위치에있는 항목을 서로 연결하고 싶습니다. 내가 대신이 될 것 LINQ를 사용하는 것이었다 그러나

For Each it as Item in Items 
    If it.Location.equals(Me.Location) 
     Me.LinkedItems.Add(it) 
    End If 
Next 

: 내가 루프 '각각의 경우'정상를 사용하여이 작업을 수행하는 경우는 다음과 같이 될 것이다

For Each it as Item in Items.Where(Function(i) i.Location.equals(Me.Location)) 
    Me.LinkedItems.Add(it) 
Next 

을 지금 내 질문은 두 번째 (LINQ) 옵션이 전체 'Items'세트를 한 번 반복하여 쿼리를 완료 한 다음 결과를 반복하여 목록에 추가하여 본질적으로 두 개의 루프를 만들거나 그 중 하나를 수행하게 할 것입니다 첫 번째 (For Each) 옵션과 같은 루프? 대답이 전자의 경우, 나는이 상황에서 LINQ를 사용하는 것이 어리석은 것이라고 가정합니다.

답변

8

하나의 루프를 수행합니다. 느리게 평가됩니다.

그러나 이보다 나은 결과를 얻을 수 있습니다. LinkedItems의 유형은 무엇입니까?

Me.LinkedItems.AddRange(Items.Where(Function(i) i.Location.equals(Me.Location))) 

더 게으른 평가를

은 기본적으로 Where이 반복자를 유지하고 만 일치하는 다음 항목 때를 발견 : 그것은 적절한 AddRange 방법이있는 경우, 당신은 할 수 있어야 그것을 요구하십시오. 그것이 게으르게 평가 만들 것 여기 yield return의 사용이다

// Error handling omitted 
public static IEnumerable<T> Where(this IEnumerable<T> source, 
            Func<T, bool> predicate) 
{ 
    foreach (T element in source) 
    { 
     if (predicate(element)) 
     { 
      yield return element; 
     } 
    } 
} 

: C#에서, 구현은 무언가 같이 될 것입니다. C# 반복기 블록에 익숙하지 않은 경우 thesearticles을 자세히 설명하는 것이 좋습니다. 물론 Where

는 반복자 블록을 사용하는 대신 "수동"구현 된 수 있지만, 위의 구현은 게으른 평가를 입증하기에 충분하다.

+0

공정하지 못함! 나는 그것을 처음으로 발견했다! ;) – RCIX

+0

굉장, 정확히 내가 뭘 찾고 있었는지 고마워! – link664

3

당신이 Items.Where의 목록을 비난하고 있기 때문에 그것은 한 번 쿼리를 할 것입니다. 귀하의 경우에는 원하는 조건의 사전 필터링 된 목록이므로 LINQ와 함께 가야합니다.

+0

+1은 Skeet보다 빠릅니다. – MarkJ

관련 문제