简体   繁体   English

如何确定 lru_cache 所需的最大大小?

[英]How to determine the required maxsize of lru_cache?

If we are creating a recursive function like one that would return the Fibonacci sequence, and using the lru_cache .. What is the real governor of the max size parameter?如果我们正在创建一个递归 function 就像一个会返回斐波那契数列并使用lru_cache .. max size参数的真正调控器是什么?

It is obvious that we only need the last two items when calculating each term.. but setting the maxsize to 2 and running the first 1000 calculation will take ages to finish.很明显,我们在计算每个术语时只需要最后两项。但是将maxsize设置为2并运行前1000计算将需要很长时间才能完成。

I tried to use a cache dictionary that only contains two elements:我尝试使用仅包含两个元素的缓存字典:

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

Then, I run a similar function with lru_cache :然后,我使用 lru_cache 运行类似的lru_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

I called the first 1000 calculation of each and the results are identical in terms of performance.我调用了每个的前 1000 次计算,结果在性能方面是相同的。 However, I am not sure how to specify the maxsize parameter.但是,我不确定如何指定maxsize参数。 I just found that, for this specific function, 2 would take ages and 3 works just fine.我刚刚发现,对于这个特定的 function,2 需要很长时间,3 可以正常工作。 My guess is that it will be storing the result, here fib1(n) , together with the last two items that were used to calculate it, fib1(n - 1) and fib1(n - 2) , but why won't the result replace the oldest item immediately?我的猜测是它将存储结果,这里fib1(n) ,以及用于计算它的最后两项, fib1(n - 1) and fib1(n - 2) ,但为什么不结果立即替换最旧的项目? Does fib1(n) take place in the cache memory before even being calculated? fib1(n)是否在计算之前就发生在缓存 memory 中? Is there a way to view the lru_cache element?有没有办法查看lru_cache元素? Maybe this would be helpful.也许这会有所帮助。

You are right, only caching 2 values is enough for Fibonacci computation .你是对的,对于 Fibonacci 计算,只缓存 2 个值就足够了

Your function doesn't work properly because recursive calls are not set in the good order .您的 function 无法正常工作,因为递归调用未按正确顺序设置 Add some print statements to your function and you will understand its behaviour.在您的 function 中添加一些打印语句,您将了解它的行为。

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

What's happening here is when you compute from fib(4) , it needs fib(3) and fib(2) .这里发生的是当您从fib(4)计算时,它需要fib(3)fib(2) But fib(3) needed fib(2) and then fib(1) , so the 2 last calls were fib(3) and fib(1 ) so you need again to recompute fib(2) .但是fib(3)需要fib(2)然后fib(1) ,所以最后两次调用是fib(3)fib(1 ) 所以你需要再次重新计算fib(2)

So you should switch fib(n - 1) and fib(n - 2) to make it work:所以你应该切换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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM