python lru_cache 中的单位是什么?

What is the unit in python lru_cache?

根据 documentation functoolslru_cache 的默认值是 128。但是没有定义单位。

Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments.

Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable.

Distinct argument patterns may be considered to be distinct calls with separate cache entries. For example, f(a=1, b=2) and f(b=2, a=1) differ in their keyword argument order and may have two separate cache entries.

If user_function is specified, it must be a callable. This allows the lru_cache decorator to be applied directly to a user function, leaving the maxsize at its default value of 128.

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

Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls

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

简答:它是存储在缓存中的数量个元素。

我们可以查一下lru_cache [GitHub]. The code is rather complicated, but in a nutshell, line 619的源码,已经有线索了:

                    full = (cache_len() >= maxsize)

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

cache_len是一个函数,returns字典中的条记录,在source code中我们可以看到:

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

该逻辑也是每次branches when it adds a new record,如果缓存已满,它将"kick out"其中一个元素:

                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 <b>full</b>:
                    # 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.
                    <b>del cache[oldkey]</b>
                    # 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.
                    <b>full = (cache_len() >= maxsize)</b>