#Código que mostra a implementação do cálculo de Fibonacci de várias maneiras e compara suas velocidades
# -*- coding: utf-8 -*-
# Versao trivial
def fib_trivial(n):
    if n == 1 or n == 2:
        return 1
    return fib_trivial(n-1) + fib_trivial(n-2)
# Versão com cache
cache = {}
def fib_cache(n):
    if n == 1 or n == 2:
        return 1
    else:
        if n not in cache:
            cache[n] = fib_cache(n-1) + fib_cache(n-2)
        return cache[n]
# Versão utilizando função, decorator
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_func(n):
    if n == 1 or n == 2:
        return 1
    return fib_func(n-1) + fib_func(n-2)

# numero que que será passado por parâmetro
numero = 35

print('Tempos para o número %d ...' %numero)

# importação do módulo time para pegar o tempo de cada execução
import time

# obtendo o tempo de Fibonacci Trivial
antes = time.time() # obtém o tempo antes da chamada da função
fib_trivial(numero) # chama a função fib_trivial
depois = time.time() # obtém o tempo depois da chamada da função
diff = depois - antes # obtém a diferença
print('Tempo Fibonacci trivial: %f segundos' %diff) # mostra o resultado

# iremos fazer coisa semelhante com as outras funções

# Obtendo o tempo de Fibonacci com cache
antes = time.time()
fib_cache(numero)
depois = time.time()
diff = depois - antes
print('Tempo Fibonacci com cache: %f segundos' %diff)

# Obtendo o tempo de Fibonacci com lru_cache
antes = time.time()
fib_func(numero)
depois = time.time()
diff = depois - antes
print('Tempo Fibonacci usando lru_cache: %f segundos' %diff)
