Programming

LINQ 기능의 순서는 중요합니까?

procodes 2020. 7. 27. 21:31
반응형

LINQ 기능의 순서는 중요합니까?


기본적으로 질문에서 알 수 있듯이 LINQ 기능의 순서는 성능 측면에서 중요 합니까? 분명히 결과는 여전히 동일해야합니다 ...

예:

myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);

둘 다 나에게 동일한 결과를 반환하지만 다른 LINQ 순서입니다. 일부 항목의 순서를 변경하면 다른 결과가 나올 수 있다는 점을 알고 있습니다. 내 주요 관심사는 동일한 결과를 얻을 때 순서가 성능에 영향을 줄 수 있는지 아는 것입니다. 그리고 내가 만든 2 개의 LINQ 호출 (OrderBy, Where)뿐만 아니라 LINQ 호출에서도 발생합니다.


사용중인 LINQ 공급자에 따라 다릅니다. LINQ to Objects에게는 확실히 차이 가 생길 수 있습니다. 우리가 실제로 가지고 있다고 가정하십시오.

var query = myCollection.OrderBy(item => item.CreatedDate)
                        .Where(item => item.Code > 3);

var result = query.Last();

즉, 필요로 전체 컬렉션을 정렬 할 다음 필터링. 백만 개의 항목이 있고 그 중 하나만 3보다 큰 코드를 가지고 있다면, 버리기 위해 결과를 주문하는 데 많은 시간을 낭비하고 있습니다.

이를 거꾸로 한 작업과 비교하여 먼저 필터링하십시오.

var query = myCollection.Where(item => item.Code > 3)
                        .OrderBy(item => item.CreatedDate);

var result = query.Last();

이번에는 필터링 된 결과 만 주문합니다. "필터와 일치하는 단일 항목"의 샘플 경우 시간과 공간 모두에서 훨씬 더 효율적입니다.

또한 쿼리가 올바르게 실행되는지 여부에 차이를 만들 있습니다. 치다:

var query = myCollection.Where(item => item.Code != 0)
                        .OrderBy(item => 10 / item.Code);

var result = query.Last();

괜찮습니다. 우리는 절대 0으로 나누지 않을 것입니다. 그러나 필터링 전에 순서 수행 하면 쿼리에서 예외가 발생합니다.


예.

그러나 성능 차이가 정확히 무엇인지 는 LINQ 공급자가 기본 식 트리를 평가하는 방법에 따라 다릅니다.

예를 들어, 쿼리는 LINQ-to-XML에 대해 두 번째 (WHERE 절이 먼저) 더 빠르지 만 LINQ-to-SQL에 대해서는 처음에 더 빠를 수 있습니다.

성능 차이가 무엇인지 정확하게 파악하려면 응용 프로그램을 프로파일 링하는 것이 좋습니다. 그럼에도 불구하고, 조기 최적화는 일반적으로 노력할 가치가 없습니다. LINQ 성능 이외의 문제가 더 중요하다는 것을 알 수 있습니다.


특정 예 에서 성능에 차이를 만들 수 있습니다 .

첫 번째 쿼리 : 3 개 이하인 항목을 포함 OrderBy하여 전체 소스 시퀀스 를 반복하여 호출해야합니다 Code. Where그런 다음 은 순서가 지정된 전체 순서 를 반복해야합니다 .

두 번째 쿼리 : Where호출은 시퀀스를 Code3보다 큰 항목으로 만 제한합니다. OrderBy그런 다음 Where호출 호출에 의해 반환 된 축소 된 시퀀스 만 통과하면됩니다 .


Linq-To-Objects에서 :

정렬은 다소 느리고 O(n)메모리를 사용 합니다. Where반면에 비교적 빠르며 일정한 메모리를 사용합니다. 따라서 Where첫 번째 작업은 더 빠르며 대규모 컬렉션의 경우 훨씬 빠릅니다.

큰 객체 힙에 대한 할당 (수집과 함께)이 내 경험상 상대적으로 비싸기 때문에 메모리 압력 감소도 중요 할 수 있습니다.


분명히 결과는 여전히 동일해야합니다 ...

실제로는 사실이 아닙니다. 특히 다음 두 줄은 다른 결과를 제공합니다 (대부분의 공급자 / 데이터 집합에 대해).

myCollection.OrderBy(o => o).Distinct();
myCollection.Distinct().OrderBy(o => o);

LINQ 쿼리를 최적화하는 방법고려할 때는주의해야 합니다. 예를 들어 선언적 버전의 LINQ를 사용하여 다음을 수행하는 경우 :

public class Record
{
    public string Name { get; set; }
    public double Score1 { get; set; }
    public double Score2 { get; set; }
}


var query = from record in Records
            order by ((record.Score1 + record.Score2) / 2) descending
            select new
                   {
                       Name = record.Name,
                       Average = ((record.Score1 + record.Score2) / 2)
                   };

어떤 이유로 든 평균을 변수에 먼저 저장하여 쿼리를 "최적화"하기로 결정한 경우 원하는 결과를 얻지 못할 수 있습니다.

// The following two queries actually takes up more space and are slower
var query = from record in Records
            let average = ((record.Score1 + record.Score2) / 2)
            order by average descending
            select new
                   {
                       Name = record.Name,
                       Average = average
                   };

var query = from record in Records
            let average = ((record.Score1 + record.Score2) / 2)
            select new
                   {
                       Name = record.Name,
                       Average = average
                   }
            order by average descending;

나는 많은 사람들이 선언적 LINQ를 객체로 사용하지는 않지만, 생각하기에 좋은 음식이라고 생각합니다.


It depends on the relevancy. Suppose if you have very few items with Code=3, then the next order will work on small set of collection to get the order by date.

Whereas if you have many items with the same CreatedDate, then the next order will work on larger set of collection to get the order by date.

So, in both case there will be a difference in performance

참고URL : https://stackoverflow.com/questions/7499384/does-the-order-of-linq-functions-matter

반응형