python #2 리스트 vs 제너레이터 비교 실습

python #2 리스트 vs 제너레이터 비교 실습 #

#2025-08-12


1. 100만 개의 숫자 합 구하기 #

1) 리스트 방식

import sys

# 1) 리스트 방식
numbers = list(range(1000000)) # 0부터 999,999 리스트 생성
list_sum = sum(numbers) # 합계 구하기
list_mem = sys.getsizeof(numbers) # 메모리 사용량 확인 (리스트 객체 크기)

print(f"리스트 합: {list_sum:,}")
print(f"리스트 메모리 사용량: {list_mem} bytes")
리스트 합: 499,999,500,000
리스트 메모리 사용량: 8000056 bytes
  • numbers=list(range(1000000)) -> sum(numbers)
    • 0~999,999를 리스트(numbers)로 만들어 합계를 구함
  • sys.getsizeof(numbers)
    • 리스트 객체의 크기를 바이트 단위로 반환

#

2) 제너레이터 방식

# 2) 제너레이터 방식
def number_gen(): # 제너레이터 함수 정의
    for i in range(1_000_000):
        yield i

gen = number_gen() # 제너레이터 객체 생성
gen_sum = sum(gen) # 합계 구하기
gen_mem = sys.getsizeof(gen) # 메모리 사용량 확인 (제너레이터 객체 크기)

print(f"제너레이터 합: {gen_sum:,}")
print(f"제너레이터 메모리 사용량: {gen_mem} bytes")
제너레이터 합: 499,999,500,000
제너레이터 메모리 사용량: 200 bytes
  • gen = number_gen() -> sum(gen)
    • 제너레이터 객체 생성, 내부적으로 하나씩 값을 생성해 합산
  • sys.getsizeof(gen)
    • 제너레이터 객체의 크기를 바이트 단위로 반환

#

3) 결과 비교

# 3) 결과 비교
print(f"메모리 사용량 비교: 리스트 {list_mem} bytes vs 제너레이터 {gen_mem} bytes")
메모리 사용량 비교: 리스트 8000056 bytes vs 제너레이터 200 bytes
  • list(range(1000000))
    • list()로 감싸면 메모리에 100만 개 원소의 배열이 만들어지므로 크기가 크다(O(N)).
  • gen = number_gen()
    • 제너레이터 객체는 “다음에 뭘 생산할지에 대한 상태”만 저장하고 실제 값(0, 1, 2, …)을 미리 메모리에 올리지 않아서 크기가 작다(O(1)).

#

2. 짝수의 제곱 총합을 계산 #

코드

import sys
import time

N = 1000000

# 1) 리스트 방식
start = time.time()
even_squares_list = [i * i for i in range(N) if i % 2 == 0]  # 모든 짝수 제곱을 리스트로 생성
even_sum_list = sum(even_squares_list) # 리스트의 모든 원소를 합산
end = time.time()

print("1) 리스트 방식")
print("합계:", even_sum_list) # 합계 출력
print("메모리 사용량:", sys.getsizeof(even_squares_list), "bytes")
print("실행 시간:", end - start, "초")

# 2) 제너레이터 방식
def even_square_gen(n): # 짝수 제곱 제너레이터
    for i in range(n): # 0부터 n-1까지 순회
        if i % 2 == 0: # 짝수인지 확인
            yield i * i # 짝수의 제곱을 하나씩 생성(yield)하여 반환
            
start = time.time()
even_sum_gen = sum(even_square_gen(N)) # 짝수 제곱을 하나씩 생성하며 합산
end = time.time()

print("2) 제너레이터 방식")
print("합계:", even_sum_gen) # 합계 출력
print("메모리 사용량:", sys.getsizeof(even_square_gen(N)), "bytes")
print("실행 시간:", end - start, "초")
print()
  • even_squares_list = [i * i for i in range(N) if i % 2 == 0] → sum(even_squares_list)
    • 모든 짝수 제곱을 리스트로 생성 후 리스트의 모든 원소를 합산
  • even_square_gen(n) → sum(even_square_gen(N))
    • 짝수 제곱을 생성하는 제너레이터 함수를 이용해 짝수 제곱을 하나씩 생성하며 합산

#

결과

1) 리스트 방식
합계: 166666166667000000
메모리 사용량: 4167352 bytes
실행 시간: 0.0649869441986084 초

2) 제너레이터 방식
합계: 166666166667000000
메모리 사용량: 208 bytes
실행 시간: 0.10016107559204102 초
  • 리스트 방식의 메모리 사용량이 4167352 bytes로 제너레이터의 메모리 사용량 208 bytes보다 컸다.
  • 리스트 방식의 sum 연산 실행 시간이 0.0649869441986084 초로 제너레이터 방식의 0.10016107559204102 초보다 빨랐다.
    • 두 방식의 속도 차이는 여러 번 수행 결과 리스트 방식이 빠른 경우도 있었고, 제너레이터 방식이 빠른 경우도 있음.

#

cf) N = 100000000에서의 비교

N=100000000
1) 리스트 방식
합계: 166666661666666700000000
메모리 사용량: 411943896 bytes
실행 시간: 8.67517375946045 초
2) 제너레이터 방식
합계: 166666661666666700000000
메모리 사용량: 208 bytes
실행 시간: 6.631064176559448 초
  • N=100000000 (100배)로 수행 결과 리스트의 sum 연산 실행 시간이 8.67517375946045 초로 제너레이터 방식의 6.631064176559448 초보다 느리게 나옴.
  • 근데 누가 빨리나와야되고 이런건 없다고하심.

#