Python のメモ化(functools.lru_cache, cache)

functools.lru_cache と functools.cache を使うと、関数の結果をキャッシュして同じ引数での再計算を避けられます。

lru_cache の基本

from functools import lru_cache

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

print(fibonacci(100))  # 瞬時に計算完了

キャッシュがないと、fibonacci(100) は天文学的な計算回数になります。lru_cache により、各引数での計算は 1 回だけになります。

cache(Python 3.9 以降)

cache は maxsize=None の lru_cache のショートカットです。

from functools import cache

@cache
def expensive_calculation(x):
    print(f"Calculating {x}")
    return x ** 2

expensive_calculation(5)  # Calculating 5 → 25
expensive_calculation(5)  # キャッシュから 25(出力なし)

キャッシュ情報の確認

print(fibonacci.cache_info())
# CacheInfo(hits=98, misses=101, maxsize=128, currsize=101)

fibonacci.cache_clear()  # キャッシュをクリア

注意点

引数はハッシュ可能でなければならない(リストや辞書は不可)
キャッシュはメモリを消費する
副作用のある関数には使わない

typed オプション

型の違いを区別するかどうかを指定できます。

@lru_cache(maxsize=128, typed=True)
def func(x):
    return x * 2

func(3)    # int の 3
func(3.0)  # float の 3.0(別エントリ)

メモ化は再帰関数や重い計算の高速化に効果的です。適切に使えばパフォーマンスが劇的に向上します。