check out Time decorator to measure your own experiments

Caching is a big and boring topic, which I won't cover theoretically. But some small code snippets/examples are interesting.

Basic implementation

lru_cache()

basically a function call and its result will be cached. Prime example is the fibbonacci sequence:

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

for i in range(100):
	print(fib(i)) # super slow after fib(30)

This is extremely slow because of repeating function calls.

from functools import lru_cache

@lru_cache() # careful without max size, the cache will never stop growing
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

for i in range(100):
	print(fib(i)) # extremely fast

Related note(s): Bit manipulations in python