加载字典的最快方法

时间:2016-11-28 19:50:39

标签: python database sqlite dictionary pickle

我有一本非常大的字典,其中包含大约400万个密钥,这些密钥是我在阅读大文本文件后获得的。我需要我的脚本运行得更快,现在我正在寻找一种正确的方法来做到这一点。我试图在某个地方保存字典以便更快地访问它,但是使用pickle实际上是将我的速度降低到150秒才能读取它!读取文本文件要快得多,这看起来很奇怪。我也尝试使用sqlite将其保存到数据库中,但这也花了太长时间。这种问题通常如何解决?

1 个答案:

答案 0 :(得分:0)

如果您使用python2,我建议使用wiredtiger作为快速键/值存储。我建议使用wiredtiger develop分支。如果您的系统上安装了swig3和python2-dev,则可以执行以下操作来安装wiredtiger:

git clone https://github.com/wiredtiger/wiredtiger --branch=develop
cd wiredtiger
./autogen.sh && ./configure --enable-python && make && make install

这是一个小型数据库类,允许使用字符串值获取和设置字符串键:

from wiredtiger import wiredtiger_open


WT_NOT_FOUND = -31803


class KV(object):

    def __init__(self, path):
        # init wiredtiger
        self._wiredtiger = wiredtiger_open(path, 'create')
        self.session = self._wiredtiger.open_session()
        # create key/value table
        self.session.create('table:kv', 'key_format=S,value_format=S')
        self.kv = self.session.open_cursor('table:kv')

    def close(self):
        self._wiredtiger.close()

    def __setitem__(self, key, value):
        self.kv.set_key(key)
        self.kv.set_value(value)
        self.kv.insert()

    def __getitem__(self, key):
        self.kv.set_key(key)
        if self.kv.search() == WT_NOT_FOUND:
            msg = "key '%s' not found" % key
            raise KeyError(msg)
        else:
            return self.kv.get_value()


kv = KV('./data')
kv['foo'] = 'bar'
assert kv['foo'] == 'bar'

如果使用wiretiger令人生畏,可以使用plyvel bindings尝试leveldb。 API非常简单,但速度要慢得多。

使用plyvel,您可以执行以下操作:

import plyvel

db = plyvel.DB('/tmp/testdb/', create_if_missing=True)
db.put('key', 'value')
# later
assert db.get('key') == 'value'

否则,如果你使用python2,那就是builtin shelve module