Función recursiva con decoración de Python.
Estoy tratando de usar mi decorador de función de tiempo para registrar el tiempo de proceso de la función de Fibonacci. Pero parece que el decorador está registrando varias veces:
def timer_func(func):
def inner_func(*args):
t1 = perf_counter()
res = func(*args)
t2 = perf_counter()
logging.log(logging.INFO, f"Hecho en {t2 - t1} segundos!")
return res
return inner_func
@timer_func
def fibonacci(x: int):
if x > 2:
return fibonacci(x - 1) + fibonacci(x - 2)
elif x == 1 or x == 2:
return 1
r = timer_func(fibonacci)(5)
print("Fibonacci %d es %d" % (5, r))
Salida:
Hecho en 7.269991328939795e-07 segundos!
Hecho en 7.840008038328961e-07 segundos!
Hecho en 0.00013806700007990003 segundos!
Hecho en 0.0006901449996803422 segundos!
davy.ai
El problema con la implementación actual del decorador
timer_func
es que se llama múltiples veces debido a la naturaleza recursiva de la funciónfibonacci
. Cada vez que se llama afibonacci
, también se llama al decoradortimer_func
, lo que resulta en múltiples registros impresos.Para solucionarlo, es necesario modificar la implementación de
timer_func
de manera que solo registre el tiempo de ejecución total de la llamada exterior afibonacci
y no de las llamadas recursivas individuales. Una forma de lograr esto es mediante la adición de una variable global que permita verificar si la llamada a la función es la llamada exterior, y solo registrar el tiempo en ese caso:Aquí, se agrega una variable global
outermost_call
que se inicializa en True y se reinicia en False después de la llamada exterior afibonacci
. El decorador solo registra el tiempo de ejecución sioutermost_call
es True. Esto asegura que solo se registre el tiempo de ejecución total de la función, y no los tiempos de ejecución individuales de las llamadas recursivas.Al utilizar esta implementación modificada de
timer_func
, la salida del código original será:lo que registra correctamente el tiempo de ejecución total de la llamada a la función
fibonacci
.