비교할 문제

generator와 list 메모리 비교에서 확인할 질문은 같은 값을 끝까지 소비할 때 list와 generator의 peak Python allocation·실행 시간은 어떻게 다른가입니다. 두 후보가 같은 값을 같은 순서로 만들고 checksum도 같아야 합니다. list의 재사용 가능성과 generator의 한 번 소비 계약은 별도로 기록합니다. 결과값, 순서, 오류 처리와 부수 효과가 다르면 같은 성능 비교가 아닙니다. 먼저 두 후보가 같은 일을 하는지 작은 입력으로 확인합니다.

원인 분석과 재현

generator는 값을 지연 생성해 전체 결과를 보관하지 않지만 한 번 소비되며 source 자원과 계산 시간이 iteration 동안 유지됩니다.

원소 100개·10만 개·100만 개에서 전체 소비와 첫 값까지만 소비하는 사례를 나눠 elapsed time과 tracemalloc peak를 봅니다. runtime version, 운영체제, CPU와 memory 제한도 결과와 함께 기록합니다.

비교 질문은 같은 값을 끝까지 소비할 때 list와 generator의 peak Python allocation·실행 시간은 어떻게 다른가입니다.

후보 유리한 조건 함께 치르는 비용
list 여러 번 순회·random access가 필요 전체 결과를 즉시 보관
generator 한 번 순회하고 streaming 소비 재사용·길이·index 접근이 없고 source 수명이 iteration까지 유지
from time import perf_counter
from tracemalloc import get_traced_memory, start, stop

def measure(name, factory):
    start()
    started = perf_counter()
    checksum = sum(factory())
    elapsed = perf_counter() - started
    _, peak = get_traced_memory()
    stop()
    print(name, {'seconds': elapsed, 'peak_bytes': peak, 'checksum': checksum})

size = 1_000_000
measure('list', lambda: [value * 2 for value in range(size)])
measure('generator', lambda: (value * 2 for value in range(size)))

해결 방안과 판정

timeit.repeat() 결과 전체를 보관하고, 작은 코드 조각의 하한을 볼 때는 공식 문서가 안내하는 최솟값도 함께 확인합니다. 서비스 지연을 재는 경우에는 median과 p95를 별도로 기록합니다. CPU time, allocation, RSS·heap, GC, I/O 중 이 작업에 직접 관련된 지표만 선택합니다. tracemalloc은 Python allocation을 보여 주지만 전체 process RSS와 native memory를 모두 설명하지 않습니다. generator는 무조건 빠른 도구가 아니라 peak memory와 첫 결과 시간을 바꾸는 선택입니다.

차이가 반복 실행의 흔들림보다 작다면 더 단순하고 읽기 쉬운 구현을 선택합니다. 차이가 충분히 크더라도 실제 요청 전체의 지연과 자원 사용이 개선되는지 확인한 뒤 적용합니다.

공식 문서와 적용 범위

문서의 기본값과 동작은 version에 따라 달라질 수 있습니다. 현재 Python 구현과 version, dependency, 입력 크기와 실행 환경에서 다시 확인합니다.