# Cache function

###### January 13, 2024

The functools module provides a `@cache` decorator to store the results of an expensive function; also known as memoize.

## No function cache

This example calls a function several times. The function sleeps for 2 seconds to represent an expensive task being performed.

``````import time

def coeffs_one(method):
"""
Get the a and b coefficients for a given method.
"""
time.sleep(2)

if method == "yaws":
a, b = 1, 2
elif method == "graham":
a, b = 2, 4
else:
a, b = 0, 0

return a, b

for _ in range(3):
ti = time.perf_counter()
a, b = coeffs_one("graham")
tf = time.perf_counter()
print(f"a is {a} | b is {b} | Elapsed {tf - ti:.4f} s")
``````

The output is shown below. Notice the elapsed time for each run is 2 seconds.

``````a is 2 | b is 4 | Elapsed 2.0036 s
a is 2 | b is 4 | Elapsed 2.0032 s
a is 2 | b is 4 | Elapsed 2.0044 s
``````

## Using function cache

This example calls a function several times and uses the `@cache` decorator to store the results.

``````import time
from functools import cache

@cache
def coeffs_two(method):
"""
Get the a and b coefficients for a given method.
"""
time.sleep(2)

if method == "yaws":
a, b = 1, 2
elif method == "graham":
a, b = 2, 4
else:
a, b = 0, 0

return a, b

for _ in range(3):
ti = time.perf_counter()
a, b = coeffs_two("graham")
tf = time.perf_counter()
print(f"a is {a} | b is {b} | Elapsed {tf - ti:.4f} s")
``````

The output for this example is shown below. Notice the elapsed time for the second and third runs is zero because the function results are cached.

``````a is 2 | b is 4 | Elapsed 2.0001 s
a is 2 | b is 4 | Elapsed 0.0000 s
a is 2 | b is 4 | Elapsed 0.0000 s
``````