Можно ли использовать lru_cache для создания синглтона?
Есть такой код:
@lru_cache()
def get_service(
redis: Redis = Depends(get_redis),
es: AsyncElasticsearch = Depends(get_elastic)
) -> Service:
return Service(es=es, redis=redis)
Можно ли такую реализацию использовать для создания синглтона? Учитывая, что Redis и ES экземпляры не меняются (то есть всегда одинаковые).
Ответы (1 шт):
Автор решения: Fox Fox
→ Ссылка
Использование @lru_cache() оправдано, если:
— функция зависит только от аргументов, не выполняет побочных действий;
— в циклах вызывается с одинаковыми аргументами;
— вычисления ресурсоёмкие: рекурсия и т.д.;
— количество уникальных входов ограничено.
Не стоит использовать, если:
— функция зависит от внешних факторов: времени, сети, БД;
— аргументы всегда уникальны;
— есть побочные действия: запись в файл, логирование, вывод и т.д.
Вот простой пример целесообразности использования кэша:
# Вычисление чисел последовательности Фибоначчи
from functools import lru_cache
import time
# Без кеша
def fib_no_cache(n):
if n < 2: return n
return fib_no_cache(n-1) + fib_no_cache(n-2)
# С кешем
@lru_cache(maxsize=None)
def fib_cache(n):
if n < 2: return n
return fib_cache(n-1) + fib_cache(n-2)
# Тест производительности
v_start = time.time()
v_result_no_cache = fib_no_cache(40)
print(f"fib_no_cache(40) = {v_result_no_cache}")
print("Время вычисления без кеша:", time.time() - v_start, "сек.")
v_start = time.time()
v_result_cache = fib_cache(40)
print(f"fib_cache(40) = {v_result_cache}")
print("Время вычисления с кешем:", time.time() - v_start, "сек.")
input("Нажмите Enter для продолжения...")
Вот результат:
fib_no_cache(40) = 102334155
Время вычисления без кеша: 15.758745670318604 сек.
fib_cache(40) = 102334155
Время вычисления с кешем: 0.000141143798828125 сек.