2

大きなファイルから辞書を作成しています。

def make_dic():
    big_dic={}
    for foo in open(bar):
           key,value=do_something(foo)
           big_dic[key]=value
def main():
    make_dic() #this takes time

私は何度もこの辞書にアクセスする必要がありますが、まったく異なるプログラムからです。このファイルを読んで辞書を作るのには時間がかかります。1つのプログラムが終了してもメモリに残る辞書を作成することは可能ですか???? 一度作成しますが、別のプログラムから何度も使用できるようにします。

4

2 に答える 2

4

これはあなたの説明に合うすべての状況で機能するわけではありませんがcPickle、スピードを上げるのに役立つはずです。

私が考えることができる唯一の問題は、データの永続性とIPCを組み合わせるのが難しいということです。したがって、これらの異なるプログラムが同時に辞書を変更している場合は、pickle役に立ちません。別のアプローチは、データベースを使用することかもしれません...

Sven Marnachの提案は気に入っていますが、検討する価値のあるトレードオフがいくつかあります。いくつかのセットアップ...

>>> pickle_file = open('pickle_foo', 'w')
>>> anydbm_file = anydbm.open('anydbm_foo', 'c')
>>> d = dict((str(i), str(j)) for i, j in zip(range(999999, -1, -1), range(0, 1000000)))

明らかに、データの入力anydbm_fileはかなり遅くなります。

>>> %timeit for k, v in d.iteritems(): anydbm_file[k] = v
1 loops, best of 3: 5.14 s per loop

この時間は、ピクルスファイルのダンプとロードにかかる時間に相当します。

>>> %timeit cPickle.dump(d, pickle_file)
1 loops, best of 3: 3.79 s per loop
>>> pickle_file.close()
>>> pickle_file = open('pickle_foo', 'r')
>>> %timeit d = cPickle.load(pickle_file)
1 loops, best of 3: 2.03 s per loop

ただし、anydbm_file作成する必要があるのは1回だけです。その後、再び開くのはほぼ瞬時です。

>>> %timeit anydbm_file = anydbm.open('anydbm_foo', 'r')
10000 loops, best of 3: 74.3 us per loop

そこanydbmには利点があります。一方で、

>>> %timeit for i in range(1, 1000): x = anydbm_file[str(i)]
100 loops, best of 3: 3.15 ms per loop
>>> %timeit for i in range(1, 1000): x = d[str(i)]
1000 loops, best of 3: 374 us per loop

からanydbm_fileキーを読み取るには、メモリ内の辞書からキーを読み取るよりも10倍の時間がかかります。ピクルスのダンプ/ロードサイクルに必要な5秒を上回るには、この違いについて多くのルックアップを実行する必要があります。ただし、そうでない場合でも、ここでの読み取り時間の違いにより、実行内容によってはパフォーマンスが低下する可能性があります。

他のオプションはSQLite3、または(同時に実行される複数のプロセスからの接続を許可する別個のデータベースサーバープロセスの場合)、psycopg2+ PostgreSQLです。

于 2012-02-16T16:57:20.950 に答える
3

キーと値が文字列である辞書を永続化する最も簡単な方法は、Pythonのanydbmモジュールです。基本的に、文字列を文字列にマッピングする辞書のように機能するファイルを作成できます。

于 2012-02-16T17:10:12.880 に答える