Python基于磁盘的字典

时间:2008-10-22 17:00:11

标签: python database dictionary disk-based

我正在运行一些动态编程代码(试图暴力反驳Collat​​z猜想= P)并且我使用dict来存储我已经计算过的链的长度。显然,它在某些时候耗尽了内存。是否有任何简单的方法可以使用dict的某些变体,当它用完房间时会将部分内容分页到磁盘上?显然它会比内存中的字典慢,并且最终可能会占用我的硬盘空间,但这可能适用于其他不那么无用的问题。

我意识到基于磁盘的字典几乎就是一个数据库,所以我使用sqlite3手动实现了一个,但是我没有以任何智能的方式完成它并让它一次查找数据库中的每个元素......它慢了300倍。

是最聪明的方法来创建我自己的一组dicts,一次只保留一个内存,并以一种有效的方式将它们分页?

10 个答案:

答案 0 :(得分:54)

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

from shove import Shove

mem_store = Shove()
file_store = Shove('file://mystore')

file_store['key'] = value

答案 1 :(得分:22)

Hash-on-disk通常使用Berkeley DB或类似的东西来解决 - Python Data Persistence documentation中列出了几个选项。你可以使用内存缓存来解决这个问题,但我会首先测试本机性能;在操作系统缓存到位的情况下,它可能会出现相同的情况。

答案 2 :(得分:7)

上次我遇到这样的问题时,我重写了使用SQLite而不是dict,并且性能大幅增加。性能的提升至少部分是由于数据库的索引功能;根据您的算法,YMMV。

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

答案 3 :(得分:7)

shelve模块可能会这样做;无论如何,测试应该很简单。而不是:

self.lengths = {}

做的:

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

唯一的问题是货架的钥匙必须是字符串,所以你必须更换

self.lengths[indx]

self.lengths[str(indx)]

(我假设你的钥匙只是整数,根据你对Charles Duffy的帖子的评论)

内存中没有内置缓存,但无论如何,您的操作系统都可以为您执行此操作。

[实际上,这并不完全正确:您可以在创建时传递参数'writeback = True'。这样做的目的是确保存储列表和架子中的其他可变东西正常工作。但副作用是整个字典缓存在内存中。既然这给你带来了麻烦,那可能不是一个好主意:-)]

答案 4 :(得分:2)

通过一点点思考,似乎你可以让shelve module做你想做的事。

答案 5 :(得分:2)

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

另一个人也这样做了:

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

看起来效率很高(而且sebsauvage是一个非常好的编码器)。也许你可以尝试一下?

答案 6 :(得分:1)

答案 7 :(得分:0)

如果有一些启发式方法可以知道下一个要检索的项目最多,那么你应该一次带一个以上的项目,并且不要忘记像Charles提到的索引。

答案 8 :(得分:0)

我还没有尝试过,但Hamster DB很有希望并且有一个Python接口。

答案 9 :(得分:0)

对于简单用例,sqlitedict 可以帮忙。但是,当您拥有更为复杂的数据库时,您可以尝试使用较受好评的答案之一。