Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Shelve对于大型词典来说太慢了,我可以做些什么来提高性能?_Python_Database_Performance_Persistence_Shelve - Fatal编程技术网

Python Shelve对于大型词典来说太慢了,我可以做些什么来提高性能?

Python Shelve对于大型词典来说太慢了,我可以做些什么来提高性能?,python,database,performance,persistence,shelve,Python,Database,Performance,Persistence,Shelve,我正在使用python存储一个表,我需要持久性 本质上,我将表存储为数字的字典字符串。整个都放在架子上 self.DB=shelve.open("%s%sMoleculeLibrary.shelve"%(directory,os.sep),writeback=True) 我使用writeback来True,因为我发现如果不这样做,系统会变得不稳定 计算完成后,系统需要关闭数据库并将其存储回数据库。现在数据库(表)大约有540MB,而且需要花费很长时间。当这个表增长到大约500MB时,时间爆炸

我正在使用python存储一个表,我需要持久性

本质上,我将表存储为数字的字典字符串。整个都放在架子上

self.DB=shelve.open("%s%sMoleculeLibrary.shelve"%(directory,os.sep),writeback=True) 
我使用
writeback
True
,因为我发现如果不这样做,系统会变得不稳定

计算完成后,系统需要关闭数据库并将其存储回数据库。现在数据库(表)大约有540MB,而且需要花费很长时间。当这个表增长到大约500MB时,时间爆炸了。但我需要一张大得多的桌子。事实上我需要两个


我可能使用了错误的坚持方式。我可以做些什么来提高性能?

对于存储一个包含
string:number
键值对的大型字典,我建议使用JSON本机存储解决方案,例如。它有一个很棒的Python API。MongoDB本身是轻量级的,速度非常快,json对象本来就是Python中的字典。这意味着您可以使用
字符串
键作为对象ID,从而实现压缩存储和快速查找

有关代码的简单程度示例,请参见以下内容:

d = {'string1' : 1, 'string2' : 2, 'string3' : 3}
from pymongo import Connection
conn = Connection()
db = conn['example-database']
collection = db['example-collection']
for string, num in d.items():
    collection.save({'_id' : string, 'value' : num})
# testing
newD = {}
for obj in collection.find():
    newD[obj['_id']] = obj['value']
print newD
# output is: {u'string2': 2, u'string3': 3, u'string1': 1}

您只需要从unicode转换回来,这很简单。

要大多少?访问模式是什么?你需要对它进行什么样的计算

请记住,如果无论如何操作都无法将表保留在内存中,那么将有一些性能限制


您可能想看看如何使用SQLAlchemy,或者直接使用类似于
bsddb
的东西,但这两种方法都会牺牲代码的简单性。但是,使用SQL,您可以根据工作负载将部分工作转移到数据库层。

根据我的经验,我建议使用Python附带的。它适用于较大的数据库和密钥编号。数以百万计的密钥和千兆字节的数据不是问题。架子在那一点上完全浪费了。另外,拥有单独的数据库进程也没有好处,它只需要更多的上下文交换。在我的测试中,我发现SQLite3是在本地处理较大数据集时使用的首选选项。运行本地数据库引擎(如mongo、mysql或postgresql)不会提供任何附加值,而且速度较慢。

我认为您的问题是因为您使用了
writeback=True
。作者说(重点是我的):

由于Python语义的原因,工具架无法知道何时 永久字典条目已修改。默认情况下,修改的对象 仅当指定给工具架时才写入(请参见示例)。如果 可选写回参数设置为True,则访问所有条目 也缓存在内存中,并在sync()和close()上写回;这 可以更方便地在持久性数据库中变异可变条目 但是,如果访问了许多条目,它可能会消耗大量资源 缓存的内存量,它可以执行关闭操作 非常慢,因为所有访问的条目都会被写回(没有办法 确定哪些访问的条目是可变的,哪些是可变的 实际上发生了变异)

您可以避免使用
writeback=True
,并确保数据只写入一次(您必须注意后续修改将丢失)

如果您认为这不是正确的存储选项(如果不知道数据是如何构造的,很难说),我建议使用sqlite3,它集成在python中(因此非常可移植),并且具有非常好的性能。它比简单的键值存储要复杂一些


请参阅其他答案以获取备选答案。

谢谢。数据实际上是一个对称的表号*号-->号,但由于shelve希望字符串作为键,我在写它时不知何故被诱导为表字符串-->号,其中字符串是带有a和b号的“a_b”,我正在开发一个理论算法,所以我现在使用的问题可能是几千兆的表。但是,当人们将该算法用于其他问题时(主要是在系统生物学中,先想大问题,然后再增加问题),找到一个可以扩大规模的解决方案是很重要的。访问是随机的,每个术语将被访问几次。我需要做的唯一计算就是获取值,如果不存在,则计算值,然后存储它。我正在考虑使用MySQL,这样数据库就不在内存中了。但这会使代码变得更复杂、更慢。谢谢。在使用shelve的大型DICT中,您是否遇到CPU使用不足的问题?您能否更详细地解释一下为什么postgresql或mysql不能提供更好的性能?