23. Function caching

(역자 주: 캐싱이라는 말이 적절한지는 모르겠지만, 이 책에서는 캐시를 동사로 많이 표현하였습니다. 하단의 캐싱은, '캐시에 저장하다' 의미로 해석 해주시면 좋을 것 같습니다.)

함수 캐싱은 전달 인자에 따른 함수의 반환 값들을 캐싱합니다. I/O 바인딩 함수가 동일한 인수를 사용하여 주기적으로 호출 될 때 시간을 절약 할 수 있습니다. 파이썬 3.2 이전 버전에서는 직접 구현해야 했습니다. 파이썬 3.2+ 부터는 lru_cache 데코레이터를 사용해서 쉽게 함수의 반환값들을 캐싱 혹은 언캐싱 할 수 있습니다.

파이썬 3.2+와 그 이전 버전에서 어떻게 사용할 수 있는지 살펴보겠습니다.

23.1 Python3.2+

피보나치 계산기를 lru_cache 를 사용해서 구현해 봅시다.

from functools import lru_cache

@lru_cache(maxsize=32)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

print([fib(n) for n in range(10)])
#Output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

maxsize 인자는 lru_cache에 캐싱해야할 최근 반환값의 수를 알려줍니다.

아래와 같이 리턴 값들을 쉽게 언캐싱 할 수 있습니다.

fib.cache_clear()

23.2 Python 2+

동일한 효과를 내는 여러가지 방법들이 있습니다. 직접 모든 캐싱 매커니즘을 만들 수도 있습니다. 전적으로 필요에 따라 만들어 쓰면 됩니다. 아래의 예시는 일반적인 캐시입니다.

from functools import wraps

def memoize(function):
    memo = {}
    @wraps(function)
    def wrapper(*args):
        if args in memo:
            return memo[args]
        else:
            rv = fuction(*args)
            memo[args] = rv
            return rv
    return wrapper

@memoize
def fibonacci(n):
    if n< 2: return n
    return fibonacci(n-1) + fibonacci(n-2)

fibonacci(25)

lru_cache로 인해 발생한 Django 버그를 잡고 있는 Caktus그룹의 좋은 글이 있습니다. 흥미로운 읽을거리이니 한 번 확인 해 보시기를.

results matching ""

    No results matching ""