1. 요소의 유무 확인: Count() != 0 보다는 Any()를 사용하자
자주 IEnumerable에 요소가 있는지 확인할 때 Count() != 0을 사용하는 경우가 있습니다. 그러나 Count()는 각 요소의 수를 O(n)의 시간에 계산합니다. 즉, 요소가 n개 있을 경우 n번의 연산이 필요하게 됩니다.
public static int Count<T>(this IEnumerable<T> enumerable)
{
var count = 0;
using(var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
count++;
}
return count;
}
이와 대조적으로, Any()는 O(1)의 시간에 요소의 유무만을 확인합니다.
public static bool Any<T>(this IEnumerable<T> enumerable)
{
using (var enumerator = enumerable.GetEnumerator())
{
return enumerator.MoveNext();
}
}
2. Count() 메소드와 Count 속성 중 어떤 것을 사용해야 할까?
IReadOnlyCollection은 IEnumerable에서 Count 속성이 추가된 파생 인터페이스입니다. List<T>와 같은 제네릭 배열형식은 이 두 인터페이스를 모두 구현하고 있습니다. 그렇기 때문에, Count 속성이 있는 경우 이를 사용하여 O(1)의 시간에 요소의 수를 가져오는 것이 좋습니다.
3. yield 사용시 주의사항
yield는 IEnumerable을 반환할 때 전체 컬렉션을 메모리에 할당하지 않기 위해 사용됩니다. 예를 들어, 아래의 메소드는 시작 값과 개수를 받아서 해당 범위의 정수를 생성합니다.
public static IEnumerable<int> MyRange(int start, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));
var end = start + count;
for (int value = start; value < end; value++)
{
yield return value;
}
}
그러나 yield를 사용할 때 주의해야 할 사항이 있습니다. 위의 예에서 count 값이 음수일 경우 예외가 발생하지만, 이 예외는 메소드를 호출한 시점이 아니라 IEnumerable을 순회할 때 발생하게 됩니다. 이를 해결하기 위해서는 local 함수를 사용하여 yield 부분을 분리해야 합니다.
4. ToList()와 ToArray()의 남발은 지양하자
ToList()나 ToArray()는 컬렉션을 새로운 변수로 깊게 복사해줍니다. LINQ의 재사용 특성을 이용하여 필요한 연산만을 수행하는 것이 좋습니다.
var numbers = Enumerable.Range(start, count);
var evenNumbers = numbers
.Where(number => (number & 0x01) == 0);
var oddNumbers = numbers
.Where(number => (number & 0x01) != 0);
Console.WriteLine("Even Numbers:");
foreach(var number in evenNumbers)
Console.WriteLine(number);
Console.WriteLine("Odd Numbers:");
foreach(var number in oddNumbers)
Console.WriteLine(number);
5. null 반환보다는 Enumerable.Empty를 사용하자
메소드에서 예외가 발생할 경우 결과값으로 null을 반환하는 것보다 Enumerable.Empty<T>()를 반환하는 것이 안전합니다. 이렇게 하면 후속 처리에서 null 체크 없이도 안전하게 컬렉션을 순회할 수 있습니다.
'C#' 카테고리의 다른 글
C#의 동적 변수란? (0) | 2023.09.29 |
---|---|
C#의 2차원 배열이란? (0) | 2023.09.28 |
Main 함수란?? (0) | 2023.09.15 |
C# 8의 System.Index 및 System.Range (0) | 2023.09.12 |
자료구조 : 선형구조와 비선형구조 (0) | 2023.09.04 |