Well, they are both recursion, because you are calling the function a()
inside itself. So, the main difference in both your functions is that there are two recursive calls on the first one and just one on the second one.
So now, on another matter:
Above code gets very slow in around 50th term.
Well, you can do something interesting to do it faster. See, because of the recursive definition of Fibonacci sequence, you are doing the same calculations more than one.
For instance: imagine you are to compute fibonacci(5)
so you need to compute fibonacci(4)
and fibonacci(3)
. But now, for fibonacci(4)
you need to compute fibonacci(3)
and fibonacci(2)
, and so on. But wait, when you finish computing fibonacci(4)
branch you already computed all fibonacci for 3 and 2, so when you go back to the other branch (fibonacci(3)
) from the first recursive call, you already have computed it. So, What if there is a way I can store thos calculations so I can access them faster? You can do it with Decorators to create a memoize class (some sort of memory to avoid repeated calculations):
This way we are going to store each computation of fibonacci(k)
on a dict
and we would check each time before a call if it exists on the dictionary, return if True
or else compute it. This way is faster
class memoize:
def __init__(self, function):
self.f = function
self.memory = {}
def __call__(self, *args):
if args in self.memory:
return self.memory[args]
else:
value = self.f(*args)
self.memory[args] = value
return value
@memoize
def fib(n):
if n <= 1:
return n
else:
return fib(n-1) + fib(n-2)
r = fib(50)
print(r)
You can see that without memoization it took too long and with memoization it only took 0.263614
.
Hope this helps