파이썬(Python)에서는 제너레이터(generator)라는 것이 있는데 이는 메모리 절약을 위한 용도로 사용된다. 이번 포스팅에서는 제너레이터(generator)에 대하여 알아보려고 한다.
제너레이터(generator)
1) 제너레이터(generator) 넌 누구냐?!
제너레이터(generator)는 쉽게 말해 return이 아닌 yield 문을 이용하여 순회 가능한(Iterable) 객체를 만들어내는 함수이다.
2) 제너레이터(generator) 생성하기
제너레이터는(generator)는 순회 가능한 객체를 yield 문으로 넘겨줘야 한다. 다음은 제너레이터를 생성하는 함수이다.
def generator(iterable):
for x in iterable:
yield x
또한 제너레이터 컴프리헨션을 통해서도 생성할 수 있다. 생성된 제너레이터는 바로 사용할 수는 없고 list 같은 것으로 감싸서 사용해야 한다. 아래 코드는 위에서 정의한 제너레이터 함수를 이용한 결과와 제너레이터 컴프리헤션을 통한 결과를 비교한 것이다. 사실 둘 다 똑같다.
gen1 = generator(range(5))
gen2 = (i for i in range(5)) ## 제너레이터 컴프리헨션
3) 제너레이터(generator) 언제 쓰나요?
먼저 같은 역할을 하는 리스트보다 제너레이터가 차지하는 메모리 용량이 훨씬적다.
import sys
test_num = 3
gen1 = (i for i in range(test_num))
list1 = list(range(test_num))
print('gen1의 용량 :', sys.getsizeof(gen1))
print('list1의 용량 :', sys.getsizeof(list1))
???
분명 제너레이터가 차지하는 메모리 용량이 적다고 했는데 이게 뭔가? 나랑 장난하자는건가? 당연히 아니다. 제너레이터의 효과는 큰 사이즈를 갖는 데이터에서 나타난다. test_num을 1,000,000으로 해보겠다.
import sys
test_num = 1000000
gen1 = (i for i in range(test_num))
list1 = list(range(test_num))
print('gen1의 용량 :', sys.getsizeof(gen1))
print('list1의 용량 :', sys.getsizeof(list1))
!!!
제너레이터의 메모리 용량은 120으로 고정된 반면 리스트의 메모리 용량은 엄청나게 늘어났다.
제너레이터 자체로 메모리 용량이 적지만 한번 사용하고 나면 바로 비어있으므로 프로그램 실행 중에도 메모리를 아낄 수 있다.
test_num = 10
gen1 = (i for i in range(test_num))
print(list(gen1)) ## 최초 한번 실행시 출력이 되고
print(list(gen1)) ## 두 번째로 사용하려고 하면 빈털털이가 되어있다.
그러나...
제너레이터의 단점 또한 존재한다. 그것은 바로 계산 속도가 일반적으로 느리다. 아래 코드는 합계를 계산할 때 제너레이터와 리스트로 주어진 경우의 시간이 얼마나 차이 나는지 확인한다.
import time
def sum_with_generator(iterable):
start = time.perf_counter()
sum((i for i in iterable))
return time.perf_counter()-start
def sum_with_list(iterable):
start = time.perf_counter()
sum(iterable)
return time.perf_counter()-start
print('제너레이터 합계 계산 시간 :', sum_with_generator(range(1000000)), 'sec')
print('리스트 합계 계산 시간 :', sum_with_list(list(range(1000000))), 'sec')
리스트로 처리하는 것이 더 약 3배 정도 더 빠르다. 따라서 메모리가 큰 이슈가 아니라면 제너레이터보다는 리스트로 처리하는 것이 더 낫다.
또한 배열을 여러 군데에서 사용한다면 이 역시 제너레이터보다 리스트로 처리하는 것이 더 낫다. 왜냐하면 앞에서도 언급했듯이 제너레이터는 한번 사용하고 나면 없어지기 때문이다.
'프로그래밍 > Python' 카테고리의 다른 글
파이썬(Python) - 딕셔너리의 키가 없는 경우 기본값(디폴트값) 설정하기 (feat. setdefault, defaultdict) (0) | 2022.09.29 |
---|---|
파이썬(Python) - 예외(Exception) 클래스(Class) 만들기 (0) | 2022.09.28 |
파이썬(Python) - 객체(Class, 클래스) 타입 확인 및 일치 여부 (feat. type, isinstance) (0) | 2022.09.27 |
파이썬(Python) - 클래스(객체) 속성 존재 확인, 속성 변경하기, 속성 값 확인, 속성 삭제 (feat. hasattr, setattr, getattr, delattr) (3) | 2022.09.26 |
파이썬(Python) 셋(Set)에 대하여 알아보기 (33) | 2022.09.22 |
댓글