Programing

LINQ .Where (predicate) .First ()가 .First (predicate)보다 빠른 이유는 무엇입니까?

lottogame 2020. 11. 6. 07:45
반응형

LINQ .Where (predicate) .First ()가 .First (predicate)보다 빠른 이유는 무엇입니까?


몇 가지 성능 테스트를하고 있는데 LINQ식이

result = list.First(f => f.Id == i).Property

보다 느립니다

result = list.Where(f => f.Id == i).First().Property

이것은 직관적이지 않은 것 같습니다. 첫 번째 표현식은 술어가 충족되는 즉시 목록에 대한 반복을 중지 할 수 있기 때문에 더 빠를 것이라고 생각했지만 결과 하위 집합을 .Where()호출하기 전에 표현식이 전체 목록을 반복 할 수 있다고 생각했을 것 .First()입니다. 후자가 단락을하더라도 First를 직접 사용하는 것보다 빠르지는 않지만 그렇습니다.

다음은 이것을 설명하는 두 가지 매우 간단한 단위 테스트입니다. TestWhereAndFirst에서 최적화를 사용하여 컴파일하면 .Net 및 Silverlight 4의 TestFirstOnly보다 약 30 % 빠릅니다. 조건자가 더 많은 결과를 반환하도록 시도했지만 성능 차이는 동일합니다.

누구 .First(fn)보다 느린 이유를 설명 할 수 있습니까 .Where(fn).First()? .Count(fn)비교했을 때 유사한 카운터 직관적 인 결과 .Where(fn).Count()봅니다.

private const int Range = 50000;

private class Simple
{
   public int Id { get; set; }
   public int Value { get; set; }
}

[TestMethod()]
public void TestFirstOnly()
{
   List<Simple> list = new List<Simple>(Range);
   for (int i = Range - 1; i >= 0; --i)
   {
      list.Add(new Simple { Id = i, Value = 10 });
   }

   int result = 0;
   for (int i = 0; i < Range; ++i)
   {
      result += list.First(f => f.Id == i).Value;
   }

   Assert.IsTrue(result > 0);
}

[TestMethod()]
public void TestWhereAndFirst()
{
   List<Simple> list = new List<Simple>(Range);
   for (int i = Range - 1; i >= 0; --i)
   {
      list.Add(new Simple { Id = i, Value = 10 });
   }

   int result = 0;
   for (int i = 0; i < Range; ++i)
   {
      result += list.Where(f => f.Id == i).First().Value;
   }

   Assert.IsTrue(result > 0);
}

나는 같은 결과를 얻었다 : where + first는 first보다 빠르다.

Jon이 언급했듯이 Linq는 지연 평가를 사용하므로 성능은 두 방법 모두에서 광범위하게 유사해야합니다.

Reflector를 살펴보면 First는 간단한 foreach 루프를 사용하여 컬렉션을 반복하지만 Where에는 다양한 컬렉션 유형 (배열, 목록 등)에 특화된 다양한 반복기가 있습니다. 아마도 이것은 작은 이점을 제공하는 것입니다.

참고URL : https://stackoverflow.com/questions/8663897/why-is-linq-wherepredicate-first-faster-than-firstpredicate

반응형