[포스트-4][LINQ] 수율-성능
[Post-4][LINQ] 수율-성능
수익률 반환을 사용하면 데이터를 쿼리할 때 성능이 크게 향상됩니다. 반복될 때만 데이터가 반환되기 때문입니다.
예를 들어 컬렉션에서 여러 쿼리를 실행해야 하는 경우 한 가지 방법은 각 쿼리에 대해 컬렉션을 반복하는 것입니다. 다른 방법은 모든 쿼리를 함께 컴파일한 다음 컬렉션에서 쿼리를 한 번 실행하는 것입니다. 두 번째 방법은 성능이 더 좋고 메모리 사용량도 적습니다.
위의 사항을 설정하기 위한 예를 살펴보겠습니다. [소스 코드는 github gist로 블로그 끝에 제공됩니다]. 이 예에서는 숫자 목록을 필터링하고 6의 배수를 얻습니다.
아래는 1부터 20까지의 숫자 목록입니다.
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
두 단계 프로세스로 필터링을 수행할 수 있습니다.
다음은 숫자를 각각 2 또는 3으로 나눌 수 있는 경우 true를 반환하는 bool DivideBy2(int x) 및 bool DivideBy3(int x)의 두 함수입니다.
private bool DivideBy2(int x)
{
if (x % 2 == 0)
{
return true;
}
else
{
return false;
}
}
private bool DivideBy3(int x)
{
if (x % 3== 0)
{
return true;
}
else
{
return false;
}
}
이제 주어진 술어를 기반으로 주어진 열거 가능 항목을 필터링하는 IEnumerable에 필터 확장을 만들 수 있습니다.
public static IEnumerable<int> **FilterWithOutYield**(
this IEnumerable<int> **enumerable**, Func<int, bool> **func**)
{
IEnumerator<int> **enumerator **= enumerable.GetEnumerator();
List<int> result = new List<int>();
**while (enumerator.MoveNext())**
{
**if (func(enumerator.Current))**
{
**result.Add(enumerator.Current);**
}
}
**return result as IEnumerable<int>;**
}
위 함수 **FilterWithOutYield **에는 두 개의 매개변수가 있습니다.
함수는 여기서 3가지 일을 합니다.
처음에 생성한 20개의 숫자 목록에서 위의 **FilterWithOutYield **를 호출해 보겠습니다.
List<int> **numbers **= new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
List<int> multiplesOfSix =
(
numbers.FilterWithOutYield(**DivideBy2**) // returns a list
.FilterWithOutYield(**DivideBy3**) // returns a list
) as List<int>;
위의 코드에서 FilterWithOutYield *는 숫자에서 *두 번 호출됩니다.
마지막으로 6으로 나눌 수 있는 숫자 목록이 반환됩니다. 여기에서 컬렉션을 두 번 반복하고 각 단계에서 새 목록을 반환하는 것을 관찰하면 됩니다.
I.e. If FilterWithOutYield is chained n times , the iterations are also proportionately increased and also the number of lists returned.
이제 Yield를 사용하여 동일한 작업을 수행하는 더 나은 방법을 살펴보겠습니다. 아래는 열거형을 필터링하고 **yield return.*을 사용하는 FilterWithYield *함수입니다.
public static IEnumerable<int> FilterWithYield(
this IEnumerable<int> enumerable, Func<int,bool> func)
{
IEnumerator<int> enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
if (**func(enumerator.Current)**)
{
**yield return enumerator.Current;**
}
}
}
참고로 위의 방법에서는 목록을 반환하지 않고 대신 수율 반환을 수행합니다.
열거형에서 이 메서드를 호출하고 어떻게 작동하는지 살펴보겠습니다.
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
IEnumerable<int> multiplesOfSixUsingYield =
numbers.FilterWithYield(**DivideBy2**) // The list is not iterated.
.FilterWithYield(**DivideBy3**); //Instead enumerator is returned
위의 코드는 **숫자 **를 반복하지 않으므로 **DivideBy2 ** 또는 **DivideBy3 **메서드 중 하나로 이동하지 않습니다. 대신 **DivideBy2 ** 및 **DivideBy3 ** 메서드를 모두 사용하여 열거 가능 항목을 필터링하는 열거자가 생성됩니다.
위 코드에서 컬렉션을 가져오려면 multiplesOfSixUsingYield *는 아래와 같이 **foreach*를 사용하거나 **ToList() *또는 *ToArray()**와 같은 확장 메서드를 사용하여 반복해야 합니다.
foreach (int x in multiplesOfSixUsingYield)
{
Console.WriteLine(x);
}
수율 반환으로 인해 열거 가능 항목은 FilterWithYield 메서드가 사용되는 횟수에 관계없이 한 번만 반복되므로 시간이 향상되고 메모리 공간도 줄어듭니다.
희망, 당신은 기사를 좋아했습니다. 계속 읽으세요. 감사합니다.
Reference
이 문제에 관하여([포스트-4][LINQ] 수율-성능), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/themeticulist/post-4linq-yield-performance-2053텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)