【问题标题】:What is the unit in python lru_cache?python lru_cache中的单位是什么?
【发布时间】:2020-09-22 19:11:35
【问题描述】:

根据documentationfunctoolslru_cache的默认值为128。但没有定义单位。

装饰器用一个可保存的记忆可调用来包装一个函数 到 maxsize 最近的通话。贵的时候可以节省时间 或使用相同的参数定期调用 I/O 绑定函数。

由于使用字典来缓存结果,因此位置和 函数的关键字参数必须是可散列的。

不同的参数模式可以被认为是不同的调用 单独的缓存条目。例如,f(a=1, b=2) 和 f(b=2, a=1) 它们的关键字参数顺序不同,并且可能有两个单独的缓存 条目。

如果指定了 user_function,它必须是可调用的。这允许 lru_cache 装饰器直接应用于用户函数,离开 默认值为 128 的 maxsize。

我的问题是,是否有任何单位,如位、字节、兆字节,或者这是一个与已用内存没有简单关系的任意数字?

【问题讨论】:

  • 如果我没记错的话,存储的 元素 的数量,所以不是字节等,而是只有 128 个元素。

标签: python functools


【解决方案1】:

简短回答:它是存储在缓存中的元素的数量

我们可以查看lru_cache [GitHub]的源代码。代码比较复杂,不过简单来说line 619已经给出了线索​​:

                    full = (cache_len() >= maxsize)

这指定缓存已满,因为cache_len() 大于或等于maxsize

cache_len 是一个函数,它返回字典中记录的数量,正如我们在source code 中看到的那样:

    cache = {}
    hits = misses = 0
    full = False
    cache_get = cache.get    # bound method to lookup a key or return None
    cache_len = cache.__len__  # get cache size without calling len()

逻辑也是每次branches when it adds a new record,如果缓存满了,就会“踢出”其中一个元素:

                if key in cache:
                    # Getting here means that this same key was added to the
                    # cache while the lock was released.  Since the link
                    # update is already done, we need only return the
                    # computed result and update the count of misses.
                    pass
                elif full:
                    # Use the old root to store the new key and result.
                    oldroot = root
                    oldroot[KEY] = key
                    oldroot[RESULT] = result
                    # Empty the oldest link and make it the new root.
                    # Keep a reference to the old key and old result to
                    # prevent their ref counts from going to zero during the
                    # update. That will prevent potentially arbitrary object
                    # clean-up code (i.e. __del__) from running while we're
                    # still adjusting the links.
                    root = oldroot[NEXT]
                    oldkey = root[KEY]
                    oldresult = root[RESULT]
                    root[KEY] = root[RESULT] = None
                    # Now update the cache dictionary.
                    del cache[oldkey]
                    # Save the potentially reentrant cache[key] assignment
                    # for last, after the root and links have been put in
                    # a consistent state.
                    cache[key] = oldroot
                else:
                    # Put result in a new link at the front of the queue.
                    last = root[PREV]
                    link = [last, root, key, result]
                    last[NEXT] = root[PREV] = cache[key] = link
                    # Use the cache_len bound method instead of the len() function
                    # which could potentially be wrapped in an lru_cache itself.
                    full = (cache_len() >= maxsize)

【讨论】:

    【解决方案2】:

    装饰器使用可保存到maxsize 最近调用

    的记忆可调用来包装函数

    该短语中的单位是“呼叫”。 IE。每个参数模式及其相应的结果。每个缓存调用的大小将取决于函数的签名;如果它返回一个占用千兆字节内存的对象,那么您可能需要减少maxsize

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 2013-12-07
      • 2017-10-11
      相关资源
      最近更新 更多