memorization
2019-01-28
예시를 통한 memorization 개념학습
memorization
-
개념요약 : 반복적으로 사용되는 계산결과를 임시 저장공간에 캐싱하여 활용함으로써 반복적인 연산을 줄이는 기법
-
아래 피보나치 함수와 같이 두단계로 나누어지는 피보나치 수열 예시로 구현
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
- 피보나치 수열의 연산시간은 크지 않은 수가 입력됨에도 불구하고 상당히 오래걸린다.
%%time
fib(40)
Wall time: 1min 38s
102334155
- 아래 구현한 ‘make_memo’ 함수의 핵심 :
-> 불필요한 연산감소
-> 중복된 계산을 ‘me’ 딕셔너리에 임시 캐싱하여 차후 반복적인 계산 시 캐싱된 데이터를 대신 활용하겠다
def make_memo(func):
me = {}
def memo(n): # memo(400) # me, func=fib
print("실제 요청 받은 숫자 n:", n)
if me.get(n):
print("캐쉬된 값 :", n)
return me[n]
else:
print("캐쉬되지 않아서 계산해야하는 값 :", n)
result = func(n)
me[n] = result
return result
return memo
- ‘make_memo’ 데코레이터를 씌우는 순간 ‘make_memo’ 함수 안에 ‘memo’함수가 작동되는 원리이다.
@make_memo
def fib(n):
## memo에 인자를 400넣는거랑 동일하다고 할 수 있다.
# me, func = fib
if n < 2:
return n
return fib(n-1) + fib(n-2)
- memorization 기법 적용 시 상당한 시간단축을 할 수 있다.
%%time
fib(5)
실제 요청 받은 숫자 n: 5
캐쉬되지 않아서 계산해야하는 값 : 5
실제 요청 받은 숫자 n: 4
캐쉬되지 않아서 계산해야하는 값 : 4
실제 요청 받은 숫자 n: 3
캐쉬되지 않아서 계산해야하는 값 : 3
실제 요청 받은 숫자 n: 2
캐쉬되지 않아서 계산해야하는 값 : 2
실제 요청 받은 숫자 n: 1
캐쉬되지 않아서 계산해야하는 값 : 1
실제 요청 받은 숫자 n: 0
캐쉬되지 않아서 계산해야하는 값 : 0
실제 요청 받은 숫자 n: 1
캐쉬된 값 : 1
실제 요청 받은 숫자 n: 2
캐쉬된 값 : 2
실제 요청 받은 숫자 n: 3
캐쉬된 값 : 3
Wall time: 4.02 ms
5
%%time
fib(5)
- 파이썬 라이브러리에도 memorization을 구현할 수 있는 내부함수가 있다.
from functools import lru_cache
@lru_cache(maxsize = 512)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
%%time
fib(400)
Wall time: 4.01 ms
176023680645013966468226945392411250770384383304492191886725992896575345044216019675