Python:构建 LRU 缓存
我在 MongoDB 中有大约 6,00,000 个条目,格式如下:
feature:category:count
其中
- feature 可以是任何单词,
- category 是正数或负数,
- < strong>count 表示某个功能在该类别的文档中出现的次数。
我想缓存前 1000 个元组,这样就不会每次都查询数据库。
如何在 Python 中构建 LRU 缓存?或者有任何已知的解决方案吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Python3.3 中的 LRU 缓存 的复杂度为 O(1)插入、删除和搜索。
该设计使用循环双向链接条目列表(按从旧到新的顺序排列)和哈希表来定位各个链接。缓存命中使用哈希表来查找相关链接并将其移动到链表的头部。缓存未命中会删除最旧的链接并在链表的头部创建一个新链接。
这是一个由 33 行非常基本的 Python 代码组成的简化(但快速)版本(仅使用简单的字典和列表操作)。它在 Python2.0 及更高版本(或 PyPy 或 Jython 或 Python3.x)上运行:
从 Python 3.1 开始,OrderedDict 使得实现 LRU 缓存变得更加简单:
The LRU cache in Python3.3 has O(1) insertion, deletion, and search.
The design uses a circular doubly-linked list of entries (arranged oldest-to-newest) and a hash table to locate individual links. Cache hits use the hash table to find the relevant link and move it to the head of the list. Cache misses delete the oldest link and create a new link at the head of the linked list.
Here's a simplified (but fast) version in 33 lines of very basic Python (using only simple dictionary and list operations). It runs on Python2.0 and later (or PyPy or Jython or Python3.x):
Starting in Python 3.1, OrderedDict makes it even simpler to implement a LRU cache:
除了 Python 3.2 中包含的版本之外,Python Cookbook 中还有 LRU 缓存配方,包括这些由 Python 核心开发人员 Raymond Hettinger 编写。
Besides the version included in Python 3.2, there are LRU cache recipes in the Python Cookbook including these by Python core developer Raymond Hettinger.
Python 3.2
functools
包含一个 LRU 缓存< /a>.您可以轻松地从 repo 中挑选它,检查您是否必须调整它以与 Python 2 配合使用(应该不会太难 - 也许使用 itertools 而不是某些内置函数 - 询问您是否需要帮助)并完成。不过,您需要将查询包装成可调用的,并确保它依赖于(可哈希的)函数参数。Python 3.2
functools
includes an LRU cache. You could easily cherrypick it from repo, check if you have to adjust it to work with Python 2 (shouldn't be too hard - perhaps usingitertools
instead of certain builtins - ask if you need help) and be done. You need to wrap the query it into a callable and make sure it depends on the (hashable) function arguments, though.还有 lru_cache 的 python 3.3 版本的向后移植,例如 this 在 python 2.7 上运行。如果您对两层缓存感兴趣(如果没有在实例中缓存,它将检查共享缓存)我创建了 lru2cache 基于 lru_cache 的向后移植。
There are also backports of the python 3.3 version of lru_cache such as this which runs on python 2.7. If you are interested in two layers of caching (if not cached in the instance it will check a shared cache) I have created lru2cache based on the backport of lru_cache.