说我有一些复杂的功能f(fvar1, ..., fvarN)
,例如:
def f(fvar1,..., fvarN):
return (complicated function of fvar1, ..., fvarN).
现在函数g(gvar1, ..., gvarM)
的表达式为f(fvar1, ..., fvarN)
,可以这样说:
def g(gvar1, ..., gvarM):
return stuff * f(gvar1 * gvar2, ..., gvar5 * gvarM) - stuff * f(gvar3, gvar2, ..., gvarM)
f
中g
的自变量可以是gvar1, ..., gvarM
的不同线性组合。
由于f
是一个复杂的函数,因此调用f
的开销很大,但是由于g
有很多实例,因此很难将值本地存储在g
中f
具有不同的参数组合。
是否有一种方法可以存储 f
的值,从而不必一次又一次调用具有相同值的f
,而不必定义{{ 1}}在f
中本地?
答案 0 :(得分:1)
是的,这称为记忆。基本思想是让</html>
根据传入的参数维护某种数据存储。然后,如果使用 same 参数进行调用,则它只是返回存储的值,而不是重新计算它。
通过基于某些规则删除参数集,可能需要限制数据存储的大小并针对您期望的调用模式进行优化。例如,如果使用参数集的次数 表示其将来可能使用,则您可能希望删除不经常使用的模式,并保留更经常使用的模式。 / p>
例如,考虑以下用于将两个数字相加的Python代码(让我们假装这是一个非常耗时的操作):
f()
可以,但是,如果使用与以前使用的相同的数字,则效率很低。您可以按如下所示添加便笺。
该代码将“记住”一定数量的计算(给定字典,可能是随机的,但我不能保证)。如果它已经已经知道知道的一对,它只会返回缓存的值。
否则,它计算值,将其存储到缓存中,并确保所述缓存不会变得太大:
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}")
我也使计算成为昂贵的操作,因此您可以看到它的实际效果(根据输出速度)。缓存的内容将立即返回,计算总和将需要一秒钟。