我正在运行一些动态编程代码(尝试暴力反驳Collatz猜想= P)并且我使用dict来存储我已经计算过的链的长度.显然,它在某些时候耗尽了内存.是否有任何简单的方法可以使用某些变体,dict
当它用完房间时会将部分内容分页到磁盘上?显然它会比内存中的字典慢,并且最终可能会占用我的硬盘空间,但这可能适用于其他不那么无用的问题.
我意识到基于磁盘的字典几乎就是一个数据库,所以我使用sqlite3手动实现了一个,但是我并没有以任何智能的方式实现它并让它一次查找数据库中的每个元素...它慢了300倍.
是最聪明的方法来创建我自己的一组dicts,一次只保留一个内存,并以一种有效的方式将它们分页?
第三方推送模块也值得一看.它与搁置非常相似,因为它是一个简单的类似dict的对象,但是它可以存储到各种后端(例如文件,SVN和S3),提供可选的压缩,甚至是线程安全的.这是一个非常方便的模块
from shove import Shove mem_store = Shove() file_store = Shove('file://mystore') file_store['key'] = value
Hash-on-disk通常使用Berkeley DB或类似的东西来解决 - Python Data Persistence文档中列出了几个选项.你可以使用内存缓存来解决这个问题,但我会首先测试本机性能; 在操作系统缓存到位的情况下,它可能会大致相同.
上次我遇到这样的问题时,我重写了使用SQLite而不是dict,并且性能大幅增加.性能的提升至少部分是由于数据库的索引功能; 根据您的算法,YMMV.
一个瘦的包装器,用于执行SQLite查询,__getitem__
并且__setitem__
编写的代码不多.
该货架模块可以做到这一点; 无论如何,测试应该很简单.代替:
self.lengths = {}
做:
import shelve self.lengths = shelve.open('lengths.shelf')
唯一的问题是货架的钥匙必须是字符串,所以你必须更换
self.lengths[indx]
同
self.lengths[str(indx)]
(我假设你的钥匙只是整数,根据你对Charles Duffy的帖子的评论)
内存中没有内置缓存,但无论如何,您的操作系统可能会为您执行此操作.
[实际上,这并不完全正确:您可以在创建时传递参数'writeback = True'.这样做的目的是确保架子中的存储列表和其他可变内容正常工作.但副作用是整个字典缓存在内存中.既然这给你带来了麻烦,那可能不是一个好主意:-)]