为什么lru_cache比在以下斐波那契计算器中作为字典实现的缓存要慢?

时间:2018-12-12 07:35:19

标签: python-3.x caching fibonacci

下面是两个使用记忆的递归函数。 cache_fibonacci使用缓存字典,而lru_cache_fibonacci使用Python的lru_cache装饰器。为什么后者这么慢?

from functools import lru_cache

cache=dict()    
def cache_fibonacci(n):
    return helper_fibonacci(n)

def helper_fibonacci(n):
    if n in cache:
        #Cache already exists
        return cache[n]
    if n==1:
        value=0
    elif n==2:
        value=1
    else:
        #Cache not set
        a=helper_fibonacci(n-1)
        b=helper_fibonacci(n-2)
        value=a+b
    cache[n]=value
    return value

@lru_cache(maxsize=1024)
def lru_cache_fibonacci(n):
    if n==1:
        return 0
    if n==2:
        return 1 
    else:
        a=rec_fibonacci(n-1)
        b=rec_fibonacci(n-2)
        return a+b  

运行时输出为:

缓存递归时间= 1.4781951904296875e-05

LRU缓存递归时间= 0.14490509033203125

1 个答案:

答案 0 :(得分:0)

LRU缓存策略:逐出最近最少使用的策略。 我们如何实现这一目标?嗯,这取决于实际的算法,但最重要的是这个。

Every node/key has an age bit. 
When you access a key x, either get or put, you reset its age to 0.

为什么?因为 x 是最近使用的,所以我们通过将其年龄设置为0来表示这一点,表示它就像一个新出生的密钥。比其他人更新。

但是,我们需要在这里再做一步。

Increment everyone's age except the one you recently accessed.

这样做是为了表示除 x 之外的所有其他人都已经超过了上一个年龄。

需要退出的所有内容(如果超出大小)是退出年龄最高的密钥。在您的情况下,它将是第1025个密钥。

In summary, it is the increment-all op that's really costly to implement.

尝试增加缓存大小,您会发现运行时更好。但是,它总是比字典小。 Python中Dict()的实现是一个哈希表。