 # Fibonacci and Optimizations

In this lesson, you’ll go over the Fibonacci series and see how to solve it recursively. You’ll also learn how to use a cache to drastically improve runtime:

``````from functools import lru_cache

def fibonacci_recursive(n):
# base cases
if n == 0:
return 0
elif n == 1:
return 1

return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)

@lru_cache(maxsize=None)
def fibonacci_recursive_optimized(n):
# base cases
if n == 0:
return 0
elif n == 1:
return 1

return fibonacci_recursive_optimized(n - 1) + fibonacci_recursive_optimized(n - 2)
`````` matteoarellano

Does the cache work in sequential ascending order? Let’s say you evaluate first on n=500 on another type of function that is not fibonacci, does the same principle apply or only for specific type of function? Bartosz Zaczyński RP Team

@matteoarellano I’m not sure if I understood your question correctly, but there’s no inherent concept of order when you use the cache. The `@lru_cache` decorator replaces your function with a wrapper function, which maintains a map of argument values and corresponding calculated results. If a particular combination of argument values is already present in the cache, then the wrapper returns a suitable value calculated previously without calling your function. Otherwise, it will call your function and keep the result for future invocations with this specific set of arguments.

You can test this out with the following code snippet. By the way, `lru_cache(maxsize=None)` is equivalent to `@cache`, which is available since Python 3.9:

``````>>> from functools import cache
>>> @cache
...     return a + b

3
3

4 