1
我有一個真正大的字典,有大約400萬個密鑰,我目前在閱讀大文本文件後會得到。我需要我的腳本運行得更快,現在我正在尋找一個合適的方法來做到這一點。我試圖把字典保存到某個地方以便更快地訪問它,但是使用pickle實際上是將我的速度降低到150秒,以便讀取它!閱讀文本文件要快得多,這看起來很奇怪。我也嘗試使用sqlite將它保存到數據庫中,但這也花了太長時間......這類問題通常如何解決?加載字典的最快方式
我有一個真正大的字典,有大約400萬個密鑰,我目前在閱讀大文本文件後會得到。我需要我的腳本運行得更快,現在我正在尋找一個合適的方法來做到這一點。我試圖把字典保存到某個地方以便更快地訪問它,但是使用pickle實際上是將我的速度降低到150秒,以便讀取它!閱讀文本文件要快得多,這看起來很奇怪。我也嘗試使用sqlite將它保存到數據庫中,但這也花了太長時間......這類問題通常如何解決?加載字典的最快方式
如果您使用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。
你現在正在加載嗎?字典如何存儲在文件中?如果它是有效的JSON,那麼使用python的'json.load'可能是最快的,你可以做到這一點......另外請注意,像'msgpack'等其他格式也可能是一個很好的候選人... – mgilson
目前我只是得到一個帶有鍵值對的文本文件,每行用空格分隔 – EliteKaffee
通常,如果可以幫助它,您將不會加載整個字典。將數據存儲在數據庫中,索引相關列並使用查詢來加載所需的部分,而不是全部。 – spectras