2016-11-28 70 views
1

我有一個真正大的字典,有大約400萬個密鑰,我目前在閱讀大文本文件後會得到。我需要我的腳本運行得更快,現在我正在尋找一個合適的方法來做到這一點。我試圖把字典保存到某個地方以便更快地訪問它,但是使用pickle實際上是將我的速度降低到150秒,以便讀取它!閱讀文本文件要快得多,這看起來很奇怪。我也嘗試使用sqlite將它保存到數據庫中,但這也花了太長時間......這類問題通常如何解決?加載字典的最快方式

+1

你現在正在加載嗎?字典如何存儲在文件中?如果它是有效的JSON,那麼使用python的'json.load'可能是最快的,你可以做到這一點......另外請注意,像'msgpack'等其他格式也可能是一個很好的候選人... – mgilson

+0

目前我只是得到一個帶有鍵值對的文本文件,每行用空格分隔 – EliteKaffee

+0

通常,如果可以幫助它,您將不會加載整個字典。將數據存儲在數據庫中,索引相關列並使用查詢來加載所需的部分,而不是全部。 – spectras

回答

0

如果您使用python2,我建議使用wiredtiger作爲快捷鍵/值存儲。我建議使用wiredtiger開發分支。只要你有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' 

如果使用有線網絡是令人生畏的,您可以使用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