Да, это называется воспоминанием. Основная идея c состоит в том, чтобы f()
поддерживал какое-то хранилище данных на основе переданных параметров. Затем, если он вызывается с теми же параметрами , он просто возвращает сохраненное значение, а не пересчитывает это.
Хранилище данных, вероятно, необходимо ограничить по размеру и оптимизировать для ожидаемого шаблона вызовов, удалив наборы параметров на основе некоторых правил. Например, если число использования набора параметров указывает на вероятность его использования в будущем, вы, вероятно, захотите удалить шаблоны, которые используются нечасто, и оставить те, которые используются чаще.
Рассмотрим, например, следующий код Python для сложения двух чисел (давайте представим, что это очень затратная по времени операция):
import random
def addTwo(a, b):
return a + b
for _ in range(100):
x = random.randint(1, 5)
y = random.randint(1, 5)
z = addTwo(x, y)
print(f"{x} + {y} = {z}")
Это работает, но, конечно, неэффективно, если вы используете те же числа, что и раньше. Вы можете добавить мемоизацию следующим образом.
Код будет «запоминать» определенное количество вычислений (возможно, случайное, учитывая словари, но я не гарантирую этого). Если он получает пару, о которой уже знает, он просто возвращает кэшированное значение.
В противном случае он вычисляет значение, сохраняя его в кеше и обеспечивая указанный кеш не становится слишком большим:
import random, time
# Cache, and the stats for it.
(pairToSumMap, cached, calculated) = ({}, 0, 0)
def addTwo(a, b):
global pairToSumMap, cached, calculated
# Attempt two different cache lookups first (a:b, b:a).
sum = None
try:
sum = pairToSumMap[f"{a}:{b}"]
except:
try:
sum = pairToSumMap[f"{b}:{a}"]
except:
pass
# Found in cache, return.
if sum is not None:
print("Using cached value: ", end ="")
cached += 1
return sum
# Not found, calculate and add to cache (with limited cache size).
print("Calculating value: ", end="")
calculated += 1
time.sleep(1) ; sum = a + b # Make expensive.
if len(pairToSumMap) > 10:
del pairToSumMap[list(pairToSumMap.keys())[0]]
pairToSumMap[f"{a}:{b}"] = sum
return sum
for _ in range(100):
x = random.randint(1, 5)
y = random.randint(1, 5)
z = addTwo(x, y)
print(f"{x} + {y} = {z}")
print(f"Calculated {calculated}, cached {cached}")
Вы увидите, что я также добавил кэшированную / рассчитанную информацию, включая окончательную строку статистики, которая показывает кеширование в действии, например:
Calculated 29, cached 71
Я также сделал вычисление дорогостоящей операцией, чтобы вы могли увидеть его в действии (по скорости вывода). Кэшированные файлы немедленно вернутся, подсчет суммы займет секунду.