patternpythonnoneModerate
functools.cache vs lru_cache: Choosing the Right Memoization
Viewed 0 times
Python 3.9+ (cache), 3.2+ (lru_cache)
functools.cachelru_cachememoizationcachinghashablememory leak
Error Messages
Problem
Developers use lru_cache without understanding that it holds references to all cached arguments and return values, preventing garbage collection and potentially leaking memory.
Solution
Use functools.cache for simple memoization; lru_cache with a size limit when memory matters.
from functools import cache, lru_cache
# cache: unbounded, simpler syntax (Python 3.9+)
# Equivalent to lru_cache(maxsize=None)
@cache
def fibonacci(n: int) -> int:
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# lru_cache: bounded, evicts least recently used
@lru_cache(maxsize=128)
def get_user(user_id: str) -> dict:
return db.fetch_user(user_id) # Caches up to 128 users
# Cache info and clearing
print(fibonacci.cache_info())
fibonacci.cache_clear()
# GOTCHA: Mutable arguments are not hashable
@cache
def process(items: list) -> int: # TypeError: unhashable type: 'list'
return len(items)
# FIX: Use tuples for hashable sequences
@cache
def process(items: tuple) -> int:
return len(items)Why
cache is syntactic sugar for lru_cache(maxsize=None). An unbounded cache is fine for pure mathematical functions with finite input ranges. Use bounded lru_cache for functions called with user-supplied inputs.
Gotchas
- All arguments must be hashable — lists, dicts, and sets cannot be used as cache keys.
- Cached functions hold strong references to arguments and results, preventing garbage collection.
- lru_cache on instance methods caches 'self', preventing instance garbage collection. Use functools.cached_property instead.
Revisions (0)
No revisions yet.