Batu Lab NotesPractical developer guides

Cache a pure Fibonacci helper with lru_cache

By Batu ยท English technical notes

Also published in our Blogger archive.

Cache a pure Fibonacci helper with lru_cache

Recursive Fibonacci is a compact illustration of overlapping work: calculating fibonacci(10) repeatedly needs values such as fibonacci(8) and fibonacci(7). Decorating the helper with functools.lru_cache(maxsize=64) stores results by argument. The first call returns 55; the second returns the same integer from the existing entry instead of expanding the recursive tree again.

The example clears the cache first so its checks describe this run. Computing values zero through ten creates eleven cached entries, and the second top-level call increases the hit count. cache_info() is useful for observing those counters and the current size without exposing the cached values themselves.

Caching suits this function because its result depends only on its integer argument and it creates no observable side effect. It is a poor fit for a function that reads a clock, a changing file, random state, or a remote service: replaying an old result could be incorrect. Cache keys must be hashable; this helper deliberately rejects booleans and non-integers. A bounded cache also means old entries can be evicted, so caching is an optimization rather than a promise that every prior result remains available.

AI assistance disclosure: This article was prepared with AI assistance.

Example

from functools import lru_cache


@lru_cache(maxsize=64)
def fibonacci(n):
    if type(n) is not int:
        raise TypeError("n must be an integer")
    if n < 0:
        raise ValueError("n must be non-negative")
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)


fibonacci.cache_clear()
first = fibonacci(10)
before = fibonacci.cache_info()
second = fibonacci(10)
after = fibonacci.cache_info()
assert first == second == 55
assert before.misses == 11
assert after.hits == before.hits + 1
assert after.currsize == 11
print(first)
print(second)

Expected output

55
55

Source: Python functools.lru_cache documentation.