Python Shelve模块的内存消耗

9 投票
1 回答
2786 浏览
提问于 2025-04-16 18:16

我被分配了一个任务,要读取一个.txt文件,这个文件记录了各种事件,并把其中的一些事件写入一个字典里。

问题是,这个文件有时候会超过3GB,这就意味着字典会变得太大,无法放进主内存里。看起来Shelve是解决这个问题的好方法。不过,由于我需要不断修改这个字典,所以必须开启writeback选项。这里让我有些担心的是,教程上说这样会让读写速度变慢,还会占用更多内存,但我找不到关于速度和内存受影响程度的具体数据。

有没有人能帮我解释一下,读写速度和内存会受到多大影响,这样我才能决定是使用writeback选项,还是为了代码效率牺牲一些可读性呢?

谢谢

1 个回答

2

对于这种大小的数据库,使用shelve真的不太合适。如果你不需要一个高可用的客户端/服务器架构,只是想把TXT文件转换成一个可以在本地内存中访问的数据库,那你应该使用ZODB

如果你需要一个高可用的解决方案,那你就得转向正式的“NoSQL”数据库,市面上有很多种可以选择。

下面是一个简单的例子,教你如何把shelve数据库转换成ZODB数据库,这样可以解决你的内存使用和性能问题。

#!/usr/bin/env python
import shelve
import ZODB, ZODB.FileStorage
import transaction
from optparse import OptionParser
import os
import sys
import re

reload(sys)
sys.setdefaultencoding("utf-8")

parser = OptionParser()

parser.add_option("-o", "--output", dest = "out_file", default = False, help ="original shelve database filename")
parser.add_option("-i", "--input", dest = "in_file", default = False, help ="new zodb database filename")

parser.set_defaults()
options, args = parser.parse_args()

if options.in_file == False or options.out_file == False :
    print "Need input and output database filenames"
    exit(1)

db = shelve.open(options.in_file, writeback=True)
zstorage = ZODB.FileStorage.FileStorage(options.out_file)
zdb = ZODB.DB(zstorage)
zconnection = zdb.open()
newdb = zconnection.root()

for key, value in db.iteritems() :
    print "Copying key: " + str(key)
    newdb[key] = value
                                                                                                                                                                                                
transaction.commit() 

撰写回答