PythonMastery
Python programs · Functions · intermediate

Memoization with functools.cache in Python

Make a slow recursive function fast by remembering its results. One line, @cache, turns millions of Fibonacci calls into a few dozen.

Memoization means storing the result of a function call, so that the next call with the same arguments returns the stored result instead of computing it again. functools.cache does this for you.

The program

python
from functools import cache

@cache
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(10))
print(fib(50))
print(fib(100))
output
55
12586269025
354224848179261915075

How it works

Counting the calls

This version counts how many times the function body runs, with and without the cache:

python
from functools import cache

calls = 0

def slow_fib(n):
    global calls
    calls += 1
    if n <= 1:
        return n
    return slow_fib(n - 1) + slow_fib(n - 2)

print(slow_fib(25), "computed in", calls, "calls")

calls = 0

@cache
def fast_fib(n):
    global calls
    calls += 1
    if n <= 1:
        return n
    return fast_fib(n - 1) + fast_fib(n - 2)

print(fast_fib(25), "computed in", calls, "calls")
print(fast_fib.cache_info())
output
75025 computed in 242785 calls
75025 computed in 26 calls
CacheInfo(hits=23, misses=26, maxsize=None, currsize=26)

The cache keeps every result until the program ends. If a function is called with many different arguments, use functools.lru_cache(maxsize=1000) instead, which keeps only the most recently used results.

Related programs: Memoization in Python without a library.

Learn the idea: Decorators: Functions That Wrap Functions, Functions & Scoping

A longer explanation: Cache a slow pure function with one decorator