수색…


지연된 실행과 즉시 실행 비교

일부 LINQ 메서드는 쿼리 개체를 반환합니다. 이 개체는 쿼리 결과를 보유하지 않습니다. 대신, 결과를 생성하는 데 필요한 모든 정보가 있습니다.

var list = new List<int>() {1, 2, 3, 4, 5};
var query = list.Select(x => {
    Console.Write($"{x} ");
    return x;
});

쿼리에 Console.Write 대한 호출이 포함되어 있지만 콘솔에 아무 것도 출력되지 않았습니다. 이것은 쿼리가 아직 실행되지 않았기 때문에 Select 전달 된 함수가 평가되지 않았기 때문입니다. 이를 지연 실행 이라고하며 쿼리의 실행은 나중에 시점까지 지연됩니다.

다른 LINQ 메서드는 쿼리를 즉시 실행 합니다. 이 메소드는 쿼리를 실행하고 값을 생성합니다.

var newList = query.ToList();

이 시점에서 Select 전달 된 함수는 원래 목록의 각 값에 대해 평가되고 콘솔에 다음 내용이 출력됩니다.

1 2 3 4 5


일반적으로 Max 또는 Count 와 같은 단일 값을 반환하거나 ToList 또는 ToDictionary 와 같은 값을 실제로 보유하는 개체를 반환하는 LINQ 메서드는 즉시 실행됩니다.

IEnumerable<T> 또는 IQueryable<T> 를 반환하는 메서드는 쿼리 개체를 반환하고 이후 시점까지 실행을 연기 할 수 있습니다.

특정 LINQ 메서드가 쿼리를 즉시 실행하는지 여부를 MSDN - C # 또는 VB.NET 에서 확인할 수 있습니다.

스트리밍 모드 (지연 평가) v 비 스트리밍 모드 (열심히 평가)

지연된 실행을 사용하는 LINQ 메서드 중 일부는 한 번에 하나의 값을 계산해야합니다. 다음 코드는 :

var lst = new List<int>() {3, 5, 1, 2};
var streamingQuery = lst.Select(x => {
    Console.WriteLine(x);
    return x;
});
foreach (var i in streamingQuery) {
    Console.WriteLine($"foreach iteration value: {i}");
}

출력됩니다 :


foreach 반복 값 : 3
5
foreach 반복 값 : 5
1
foreach 반복 값 : 1
2
foreach 반복 값 : 2

왜냐하면 Select 전달 된 함수는 foreach 반복마다 평가되기 때문입니다. 이를 스트리밍 모드 또는 지연 평가라고 합니다.


다른 LINQ 메서드 - 정렬 및 그룹화 연산자 - 모든 값을 반환 해야 값을 반환 할 수 있습니다.

var nonStreamingQuery = lst.OrderBy(x => {
    Console.WriteLine(x);
    return x;
});
foreach (var i in nonStreamingQuery) {
    Console.WriteLine($"foreach iteration value: {i}");
}

출력됩니다 :


5
1
2
foreach 반복 값 : 1
foreach 반복 값 : 2
foreach 반복 값 : 3
foreach 반복 값 : 5

이 경우 값을 foreach 에 오름차순으로 생성해야하므로 모든 요소를 ​​먼저 평가해야 가장 작은 것이고 그 다음으로 작은 것이 결정됩니다. 이를 비 스트리밍 모드 또는 열렬한 평가라고 합니다.


특정 LINQ 메서드가 스트리밍 또는 비 스트리밍 모드를 사용하는지 여부는 MSDN - C # 또는 VB.NET 에서 확인할 수 있습니다.

지연 실행의 이점 - 쿼리 작성

지연된 실행은 값을 평가하기 전에 여러 작업을 결합하여 최종 쿼리를 작성할 수있게합니다.

var list = new List<int>() {1,1,2,3,5,8};
var query = list.Select(x => x + 1);

이 시점에서 쿼리를 실행하면 :

foreach (var x in query) {
    Console.Write($"{x} ");
}

우리는 다음과 같은 결과를 얻을 것이다 :

2 2 3 4 6 9

그러나 더 많은 연산자를 추가하여 쿼리를 수정할 수 있습니다.

Console.WriteLine();
query = query.Where(x => x % 2 == 0);
query = query.Select(x => x * 10);

foreach (var x in query) {
    Console.Write($"{x} ");
}

산출:

20 20 40 60

지연 실행의 이점 - 현재 데이터 쿼리

지연 실행을 사용하면 쿼리 할 데이터가 변경된 경우 쿼리 개체는 정의 시점이 아닌 실행시 데이터를 사용합니다.

var data = new List<int>() {2, 4, 6, 8};
var query = data.Select(x => x * x);

이 시점에서 즉석 메서드 또는 foreach 를 사용하여 쿼리를 실행하면 쿼리는 짝수 목록에서 작동합니다.

그러나 목록의 값을 변경하면

data.Clear();
data.AddRange(new [] {1, 3, 5, 7, 9});

또는 새 목록을 data 할당하더라도

data = new List<int>() {1, 3, 5, 7, 9};

쿼리를 실행하면 쿼리는 새로운 data 값에 대해 작동 data .

foreach (var x in query) {
    Console.Write($"{x} ");
}

다음을 출력합니다 :

1 9 25 49 81



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow