# Python fibonacci sequence optimized 4 examples

In this article we will have a look of:

- simple Fibonacci with recursion
- Fibonacci numbers with memoization and recursion
- Fibonacci sequence with bottom-up and not recursion
- Fibonacci by object and method

## Fibonacci sequence basic example

The simplest is the closest to the definition for producing numbers of Fibonacci is:

```
def fib(i):
if i <= 2:
return 1;
else:
f = fib(i-1) + fib(i-2)
print('calc', i)
return f
print(fib(6))
```

result:

```
calc 3 calc 4 calc 3 calc 5 calc 3 calc 4 calc 6
8
```

As you can see we are calculating some numbers several times. For example we are calculating 3 - 3 times which is a performance issue for bigger numbers. In order to improve the result we can use memoization which is part of dynamic programing.

## Fibonacci numbers memoization example

Memoization will allow us to calculate each number in the sequence only once:

```
def fibMemo(i):
if i in memo:
return memo[i]
if i <= 2:
return 1;
else:
f = fibMemo(i-1) + fibMemo(i-2)
memo[i] = f
print('calc', i, memo)
return f
memo = {}
print(fibMemo(6))
```

result:

```
calc 3 {3: 2}
calc 4 {3: 2, 4: 3}
calc 5 {3: 2, 4: 3, 5: 5}
calc 6 {3: 2, 4: 3, 5: 5, 6: 8}
8
```

We are using hint for the values which are calculated already and we are saving calculations - for 3 we have only 1. Similar approach to this one is bottom-up approach which is not using recursion but for loop.

## Fibonacci sequence with bottom-up

It's similar approach to memoization without using recursion. In some cases could be slightly better than memoization :

```
def fibBottom(i):
fib = {}
for k in range(i+1):
if k <= 2: f = 1
else:
f = fib[k - 1] + fib[k - 2]
print('calc', k , fib)
fib[k] = f
return fib[i]
print(fibBottom(6))
```

result:

```
calc 3 {0: 1, 1: 1, 2: 1}
calc 4 {0: 1, 1: 1, 2: 1, 3: 2}
calc 5 {0: 1, 1: 1, 2: 1, 3: 2, 4: 3}
calc 6 {0: 1, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5}8}
8
```

## Fibonacci numbers with class and method OOP

Using class and method is also fast and efficient way.:

```
class Fibon:
old = 1
fib = 1
current = 1
def next(self):
print('calc', self.current , self.fib)
newFib = self.fib + self.old;
self.old = self.fib;
self.fib = newFib;
self.current+=1
return fib;
fibon = Fibon()
while(fibon.current < 5):
k = fibon.next()
print(fibon.fib)
```

result:

```
calc 1 1
calc 2 2
calc 3 3
calc 4 5
8
```

You can check also this example in Java:

Java 8 fast non recursive Fibonacci

## Benchmark of the methods

Simple test and bench mark for all four examples with Fibonacci 40 is giving me:

```
102334155 - bench simple took - 35742.329ms.
102334155 - bench memo took - 0.034ms.
102334155 - bench bottom - took 0.025ms.
102334155 - bench class - took 0.044ms.
```

as you can see the pure recursion is really slow and inefficient in comparison to the other methods.