Python 如何确定所需的lru_缓存的最大大小?
如果我们正在创建一个递归函数,比如返回斐波那契序列的函数,并使用Python 如何确定所需的lru_缓存的最大大小?,python,caching,memoization,Python,Caching,Memoization,如果我们正在创建一个递归函数,比如返回斐波那契序列的函数,并使用lru\u缓存。。max size参数的实际调节器是什么 很明显,在计算每项时,我们只需要最后两项。。但是,将maxsize设置为2并运行第一次1000计算需要很长时间才能完成 我尝试使用仅包含两个元素的缓存字典: fib_cache = {0: 1, 1: 1} def fib(n): if n == 1: val = 1 elif n == 2: val = 1 elif
lru\u缓存
。。max size
参数的实际调节器是什么
很明显,在计算每项时,我们只需要最后两项。。但是,将maxsize
设置为2
并运行第一次1000
计算需要很长时间才能完成
我尝试使用仅包含两个元素的缓存字典:
fib_cache = {0: 1, 1: 1}
def fib(n):
if n == 1:
val = 1
elif n == 2:
val = 1
elif n > 2:
val = fib_cache[0] + fib_cache[1]
fib_cache[0] = fib_cache[1]
fib_cache[1] = val
return val
然后,我使用lru\u cache
运行了一个类似的函数:
from functools import lru_cache
@lru_cache(maxsize=3)
def fib1(n):
if n == 1:
val = 1
elif n == 2:
val = 1
elif n > 2:
val = fib1(n - 1) + fib1(n - 2)
return val
我调用了每种方法的前1000次计算,结果在性能方面是相同的。但是,我不确定如何指定maxsize
参数。我刚刚发现,对于这个特定的函数,2个需要时间,3个可以正常工作。我的猜测是,它将存储结果,这里是fib1(n)
,以及用于计算结果的最后两项,fib1(n-1)和fib1(n-2)
,但是为什么结果不会立即替换最旧的项呢?fib1(n)
在计算之前是否在缓存中发生?
是否有方法查看
lru\U缓存
元素?也许这会有帮助。你是对的,仅缓存2个值就足以进行斐波那契计算
您的函数无法正常工作,因为递归调用的设置顺序不正确。在函数中添加一些print语句,您将了解它的行为
from functools import lru_cache
@lru_cache(maxsize=2)
def fib(n):
print(f'calling fib({n})')
if n == 1:
val = 1
elif n == 2:
val = 1
elif n > 2:
val = fib(n - 1) + fib(n - 2)
print(f'fib({n}) is being computed')
return val
fib(5)
# calling fib(5)
# calling fib(4)
# calling fib(3)
# calling fib(2)
# fib(2) is being computed
# calling fib(1)
# fib(1) is being computed
# fib(3) is being computed
# calling fib(2)
# fib(2) is being computed
# fib(4) is being computed
# calling fib(3)
# calling fib(1)
# fib(1) is being computed
# fib(3) is being computed
# fib(5) is being computed
这里发生的事情是当你从fib(4)
计算时,它需要fib(3)
和fib(2)
。但是fib(3)
需要fib(2)
然后fib(1)
,所以最后两个调用是fib(3)
和fib(1
),所以您需要再次计算fib(2)
因此,您应该切换fib(n-1)
和fib(n-2)
使其工作:
@lru_cache(maxsize=2)
def fib(n):
if n == 1:
val = 1
elif n == 2:
val = 1
elif n > 2:
val = fib(n - 2) + fib(n - 1)
return val
作为旁注,有一种更快的斐波那契数分治算法可以回答您的问题缓存大小和缓存失效与其说是精确的科学,不如说是一门艺术。通常没有已知的精确限值,试错法揭示了每个限值的最佳参数case@Nikos谢谢,这是一个很酷的方法,但它只适用于斐波那契序列。我希望找到一种更通用的方法来指定所需的缓存。。假设您有一个更复杂的函数,它在每次运行时返回一个值列表,而不是单个值。。正如你所说,反复试验也许是一个好办法。。谢谢你,酷。。我认为只要它们在同一行中调用,顺序就不重要。。但不知怎的,它起作用了:)谢谢@mbh86