Python基于磁盘的字典

我正在运行一些dynamic编程代码(试图蛮力反驳Collat​​z猜想= P),我正在使用一个字典来存储我已经计算的链的长度。 很明显,它在某个时候耗尽了内存。 是否有任何简单的方法来使用dict一些变种,当它的空间不足时,它将自己的部分页面分页到磁盘? 显然它会比内存中的字典慢,它可能最终会吃掉我的硬盘空间,但是这可能适用于其他问题并不那么徒劳。

我意识到一个基于磁盘的字典几乎是一个数据库,所以我手动实现一个使用sqlite3,但我没有以任何聪明的方式做,并一次查找数据库中的每个元素…这是慢了大约300倍。

最聪明的办法就是创build自己的一套词典,一次只保留一个词,然后用一些有效的方式把它们分开。

通常用Berkeley DB或类似的东西解决磁盘上的散列问题 – Python数据持久性文档中列出了几个选项。 你可以用内存中的caching作为前端,但是我会首先testing本机的性能。 操作系统caching到位可能会出现相同的情况。

第三方推送模块也值得一看。 这与搁置非常相似,它是一个简单的类似于字典的对象,但它可以存储到各种后端(如文件,SVN和S3),提供可选压缩,甚至是线程安全。 这是一个非常方便的模块

 from shove import Shove mem_store = Shove() file_store = Shove('file://mystore') file_store['key'] = value 

上次我遇到这样的问题时,我重写了使用SQLite而不是一个字典,并且有了巨大的性能提升。 性能提高至less部分是由于数据库的索引能力; 取决于你的algorithm,YMMV。

__getitem____setitem__中执行SQLite查询的瘦包装器不需要太多的代码来编写。

搁架模块可以做到这一点; 无论如何,testing应该很简单。 代替:

 self.lengths = {} 

做:

 import shelve self.lengths = shelve.open('lengths.shelf') 

唯一的问题是,货架上的钥匙必须是string,所以你必须更换

 self.lengths[indx] 

 self.lengths[str(indx)] 

(我假设你的键只是整数,根据你对查尔斯·达菲的post的评论)

内存中没有内置的caching,但是无论如何,您的操作系统可能会为您做这些。

[事实上,这不是真的:你可以在创build时传递参数'writeback = True'。 这样做的目的是确保存储列表和其他可变的东西在货架上正常工作。 但是一个副作用是整个字典被caching在内存中。 由于这给你造成了问题,这可能不是一个好主意:-)]

有一点点思考,似乎你可以让搁置模块做你想做的事情。

我读过你认为搁置太慢,你试图用SQLite破解你自己的字典。

另一个也是这样做的:

http://sebsauvage.net/python/snyppets/index.html#dbdict

看起来很有效率(sebsauvage是一个相当不错的编码器)。 也许你可以试试看?

从GvR读取这个问题的答案;) 使用Python在2MB的RAM中对一百万个32位整数进行sorting

如果有一些启发式的方法可以知道哪些是最有可能被检索的项目,那么您应该一次带多个项目,而且不要忘记Charles提到的索引。

我还没有尝试,但仓鼠数据库是有希望的,并有一个Python界面。