linq
메소드 실행 모드 - 즉각적인, 지연된 스트리밍, 지연된 비 스트리밍
수색…
지연된 실행과 즉시 실행 비교
일부 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