Python lru_cache : how can currsize < misses < maxsize?

标签 python caching lru

我有一个类,其方法用 lru_cache annotation 注释:

CACHE_SIZE=16384

class MyClass:
    [...]

    @lru_cache(maxsize=CACHE_SIZE)
    def _my_method(self, texts: Tuple[str]):
       <some heavy text processing>

    def cache_info(self):
        return self._my_method.cache_info()

运行一段时间后,通过cache_info()方法查看缓存统计信息:

c = MyClass()
[...]
c.cache_info()

{
  "hits":9348,
  "misses":4312,
  "maxsize":16384,
  "currsize":2588
}

我的问题是:currsize 如何小于 misses 且小于 maxsize

我的理解:对于每次未命中,结果都会添加到缓存中,从而增加当前大小。只有当当前大小达到最大大小时,才会删除缓存的结果。由于此处尚未达到最大大小,因此应缓存每个未命中,因此此时 currsize 应等于 misses。 然而,这似乎不是它的工作方式。

最佳答案

如果您的程序是多线程的或递归的 - 基本上,任何类型的 _my_method() 可能会在另一个调用部分完成时再次调用的情况 - 那么就可以看到行为你正在经历。

lru_cache() 是线程感知的,并使用以下一组步骤进行大小限制缓存:

  • 从包装函数的参数中生成哈希键
  • 将缓存锁定在 with block 中:
    • 在缓存中查找key
    • 如果key在缓存中,返回缓存值
    • 否则,如果 key 不在缓存中,则将 misses 增加 1
  • 调用包装函数
  • 再次锁定缓存
    • 如果结果在缓存中,则返回
    • 如果结果仍然不在缓存中,添加它,可能会删除旧条目等。

换句话说,缓存的值可能已在调用包装函数时由另一个线程添加,但仍算作未命中。如果您多次调用 _my_method() 查找相同的缺失键,导致 misses 递增,但随后导致键出现在缓存中 _my_method() 完成,misses 会高于currsize

关于Python lru_cache : how can currsize < misses < maxsize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68951594/

相关文章:

python - 无法在同一个 django View 中使用两个模型

python - 如何使用 Python 从 doc/docx 文件中提取数据

c# - 在 asp.net mvc 中以编程方式中止 OutputCache 持续时间

python-3.x - 为什么 lru_cache 比作为以下斐波那契计算器的字典实现的缓存慢?

algorithm - 最近最少使用 (LRU) 分页算法总是比 FIFO 更有效?

Python:构建 LRU 缓存

python - 我怎样才能杀死后台python进程?

python - 如何更改两个数据帧之间公共(public)元素的值?

c# - Apache ignite 缓存查看器(如 Redis 桌面管理器)

c++ - unordered_map 储备的行为