LINQ 식에서 다중 열거

발행: (2025년 12월 15일 오후 03:00 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

왜 다중 열거가 문제인가

  • 반복 작업 – 각 열거는 시퀀스의 시작부터 시작하는 새로운 열거자를 생성합니다.
  • 리소스 소비 – 데이터베이스, 웹 서비스 호출, 파일 읽기와 같은 쿼리의 경우, 각 열거가 비용이 많이 드는 작업을 다시 수행합니다.
  • 예기치 않은 부작용 – 일부 열거자는 상태를 갖는 부작용(예: 로깅, 카운터)을 가지고 있어 여러 번 실행될 수 있습니다.

조기 물리화

반복 열거를 피하려면, 한 번 이상 순회할 필요가 있음을 알게 되는 즉시 시퀀스를 물리화합니다. 물리화는 지연된 IEnumerable를 구체적인 컬렉션(List, T[] 등)으로 변환하여 기본 쿼리를 다시 실행하지 않고 재사용할 수 있게 합니다.

// Lazy sequence
IEnumerable numbers = Enumerable.Range(1, 10);

// This will enumerate the sequence twice
foreach (int n in numbers) Console.WriteLine(n);
foreach (int n in numbers) Console.WriteLine(n);

ToList()(또는 ToArray())로 물리화하기

IEnumerable numbers = Enumerable.Range(1, 10);
List materializedNumbers = numbers.ToList();   // materialized once

// Both loops now use the same in‑memory list
foreach (int n in materializedNumbers) Console.WriteLine(n);
foreach (int n in materializedNumbers) Console.WriteLine(n);

모범 사례

권장 사항이유
컬렉션을 여러 번 순회할 경우 조기에 물리화한다.원본 소스의 단일 열거를 보장합니다.
ToList() 또는 ToArray() 를 사용해 IEnumerable를 구체 타입으로 변환한다.빠른 인덱스 접근을 제공하고 반복 쿼리 실행을 방지합니다.
여러 번 열거될 메서드 매개변수 를 문서화한다.호출자에게 잠재적인 성능 비용을 알립니다.
코드를 프로파일링 하여 동일 IEnumerable가 반복 열거되는 핫스팟을 찾는다.최적화 노력을 가장 중요한 부분에 집중할 수 있게 합니다.
지연 실행을 이해한다 (파트 1 참조)지연된 쿼리에서 의도치 않은 다중 패스를 방지합니다.

다중 열거가 특히 해로운 시나리오

  • 데이터베이스 쿼리 – 각 열거가 SQL 명령을 다시 실행하여 여러 번 라운드 트립을 발생시킵니다.
  • 외부 API 호출 – 재열거가 반복적인 네트워크 요청을 트리거할 수 있습니다.
  • 파일 I/O – 파일을 여러 번 읽으면 I/O 대역폭이 낭비됩니다.
  • 비싼 계산 – 복잡한 변환을 재계산하면 성능이 저하됩니다.

빠른 체크리스트

  • 컬렉션을 한 번 이상 순회해야 하나?
  • 그렇다면 ToList()/ToArray()를 한 번 호출하고 결과를 재사용한다.
  • 여러 번 열거될 매개변수를 문서화했는가?
  • 숨겨진 다중 열거가 남아 있지 않은지 코드를 프로파일링했는가?

추가 자료

Back to Blog

관련 글

더 보기 »

.NET에서 NuGet 패키지 사용 마스터하기

NuGet은 실제로 무엇인가요? NuGet을 .NET의 Amazon이나 Mercado Libre라고 생각해 보세요. 가구의 모든 나사를 직접 만들지 않고, 가게에 주문하듯이요. - 패키지…