El caching de funciones es una técnica utilizada para mejorar la eficiencia de los programas al almacenar el resultado de una función para entradas específicas.
Cuando la función es llamada nuevamente con las mismas entradas, el resultado almacenado se retorna inmediatamenteevitando el cálculo redundante.
El caching es especialmente útil en contextos donde
- Las funciones son costosas en términos de tiempo de ejecución
- Las mismas entradas son usadas repetidamente.
Implementación de Caching con functools.lru_cache
El módulo functools
en Python incluye el decorador @lru_cache
(Least Recently Used cache), que es una forma simple y eficiente de implementar caching en funciones.
Este decorador mantiene un número fijo de resultados y elimina los menos utilizados cuando se alcanza el límite.
from functools import lru_cache
@lru_cache(maxsize=128)
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
print(factorial(10)) # Cálculo normal
print(factorial(10)) # Resultado cacheado
En este ejemplo,
- El decorador
@lru_cache(maxsize=128)
cachea los resultados de la funciónfactorial
hasta un máximo de 128 entradas. - Las subsecuentes llamadas con los mismos argumentos retornan el resultado cacheado en lugar de recalcularlo.
El decorador @lru_cache
admite los siguientes parámetros.
Parámetro | Descripción |
---|---|
maxsize | Define el tamaño máximo del cache. Un valor de None indica un tamaño ilimitado |
typed | Si se establece en True , se considerarán diferentes tipos de argumentos como entradas diferentes en el cache |
Implementación Manual de Caching
Además de lru_cache
también podemos implementar el caching manualmente utilizando estructuras de datos como diccionarios.
cache = {}
def factorial(n):
if n in cache:
return cache[n]
if n == 0:
result = 1
else:
result = n * factorial(n-1)
cache[n] = result
return result
print(factorial(10)) # Cálculo normal
print(factorial(10)) # Resultado cacheado
En este ejemplo
- En el diccionario
cache
almacena los resultados defactorial
- Antes de calcular el resultado, verificamos si ya está almacenado en el cache, retornando el valor almacenado si está disponible
En general, el resultado es parecido al que obtendríamos usando @lru_cache
. Pero saber hacerlo manualmente es útil, si tenemos que personalizar el comportamiento del cache