중간 구체화(C#)
주의하지 않으면 어떤 상황에서는 쿼리에서 컬렉션이 조기에 구체화되어 애플리케이션의 메모리 및 성능 프로필이 크게 변경될 수 있습니다. 일부 표준 쿼리 연산자는 단일 요소를 생성하기 전에 소스 컬렉션을 구체화합니다. 예를 들어, Enumerable.OrderBy는 먼저 전체 소스 컬렉션을 반복한 다음 모든 항목을 정렬하고 마지막으로 첫 번째 항목을 생성합니다. 즉, 정렬된 컬렉션의 첫 번째 항목을 가져오는 것은 비용이 많이 들며 그 다음에 나오는 각 항목에는 비용이 많이 들지 않습니다. 해당 쿼리 연산자가 다른 방식으로 작업하는 것은 불가능할 것입니다.
예: 구체화를 유발하는 ToList
를 호출하는 메서드를 추가합니다.
이 예는 체인 쿼리 예(C#)의 예를 변경합니다. 즉, 원본을 반복하기 전에 ToList를 호출하도록 AppendString
메서드가 변경되어 구체화됩니다.
public static class LocalExtensions
{
public static IEnumerable<string>
ConvertCollectionToUpperCase(this IEnumerable<string> source)
{
foreach (string str in source)
{
Console.WriteLine("ToUpper: source >{0}<", str);
yield return str.ToUpper();
}
}
public static IEnumerable<string>
AppendString(this IEnumerable<string> source, string stringToAppend)
{
// the following statement materializes the source collection in a List<T>
// before iterating through it
foreach (string str in source.ToList())
{
Console.WriteLine("AppendString: source >{0}<", str);
yield return str + stringToAppend;
}
}
}
class Program
{
static void Main(string[] args)
{
string[] stringArray = { "abc", "def", "ghi" };
IEnumerable<string> q1 =
from s in stringArray.ConvertCollectionToUpperCase()
select s;
IEnumerable<string> q2 =
from s in q1.AppendString("!!!")
select s;
foreach (string str in q2)
{
Console.WriteLine("Main: str >{0}<", str);
Console.WriteLine();
}
}
}
이 예제는 다음과 같은 출력을 생성합니다.
ToUpper: source >abc<
ToUpper: source >def<
ToUpper: source >ghi<
AppendString: source >ABC<
Main: str >ABC!!!<
AppendString: source >DEF<
Main: str >DEF!!!<
AppendString: source >GHI<
Main: str >GHI!!!<
이 예제에서 ToList을 호출하면 AppendString
이 첫 번째 항목을 생성하기 전에 전체 소스를 열거하는 것을 확인할 수 있습니다. 소스가 큰 배열인 경우에는 애플리케이션의 메모리 프로필이 크게 변경됩니다.
이 자습서의 마지막 문서에 표시된 대로 표준 쿼리 연산자를 함께 연결할 수도 있습니다.
참고 항목
GitHub에서 Microsoft와 공동 작업
이 콘텐츠의 원본은 GitHub에서 찾을 수 있으며, 여기서 문제와 끌어오기 요청을 만들고 검토할 수도 있습니다. 자세한 내용은 참여자 가이드를 참조하세요.
.NET