Что делать, если тестируемая функция выполняет много времени на повторяющиеся операции внутри нее?
Ответ от нейросети
sobes.tech AI
Использовать кэширование результатов выполнения функции.
Наиболее распространенные подходы в Python:
-
@functools.lru_cache: Встроенный декоратор для кэширования результатов функции на основе недавнего использования (Least Recently Used). Удобен для кэширования результатов функций с детерминированным поведением, зависящим от входных аргументов.# Декоратор lru_cache import functools @functools.lru_cache(maxsize=128) def expensive_function(n): // Имитация дорогостоящей операции import time time.sleep(1) return n * 2 // Первое выполнение (долго) result1 = expensive_function(5) print(f"Первый вызов с 5: {result1}") // Второе выполнение (быстро, из кэша) result2 = expensive_function(5) print(f"Второй вызов с 5: {result2}") -
Ручной кэш (словарь): Подходит, когда требуется более тонкий контроль над кэшированием или когда декоратор
lru_cacheнеприменим (например, для методов объектов или когда аргументы функции не хешируемы).// Ручной кэш cache = {} def another_expensive_function(n): if n in cache: return cache[n] else: // Имитация дорогостоящей операции import time time.sleep(1) result = n * 3 cache[n] = result return result // Первое выполнение (долго) result3 = another_expensive_function(10) print(f"Первый вызов с 10: {result3}") // Второе выполнение (быстро, из кэша) result4 = another_expensive_function(10) print(f"Второй вызов с 10: {result4}") -
Внешние системы кэширования: Для распределенных систем или более крупномасштабного кэширования можно использовать внешние системы, такие как Redis или Memcached.
// Пример использования Redis (псевдокод) import redis r = redis.Redis(host='localhost', port=6379, db=0) def redis_cached_function(arg): cache_key = f"cache:expensive_op:{arg}" cached_result = r.get(cache_key) if cached_result: return cached_result.decode('utf-8') // Декодируем байты Redis else: // Дорогостоящая операция result = f"Результат для {arg}" r.set(cache_key, result, ex=3600) // Кэшируем на 1 час return result // Использование print(redis_cached_function("параметр_1")) print(redis_cached_function("параметр_1")) // Получение из Redis
Выбор подхода зависит от конкретных требований:
@functools.lru_cache- простота, автоматическое управление размером кэша.- Ручной кэш - гибкость, контроль.
- Внешние системы - распределенное кэширование, персистентность.
Перед внедрением кэширования важно убедиться, что функция является детерминированной (возвращает одинаковый результат для одинаковых входных данных) и что затраты на вычисление перевешивают затраты на хранение и извлечение из кэша.