0

ファイル内の行からリストを作成する必要があるユースケースがあります。この操作は、分散ネットワーク上で数百回実行される可能性があります。私は次の明らかな解決策を使用してきました:

with open("file.txt") as f:
    ds = f.readlines()

このリストを一度作成し、それをファイルにピクルしてから、そのファイルを使用して各ノードのデータをピクル解除するほうがよいのではないかと思いました。

これを行うと、パフォーマンスが向上しますか?

4

1 に答える 1

5

これを行うと、パフォーマンスが向上しますか?

テストして見てください!

try:
    import cPickle as pickle
except:
    import pickle
import timeit

def lines():
    with open('lotsalines.txt') as f:
         return f.readlines()

def pickles():
    with open('lotsalines.pickle', 'rb') as f:
        return pickle.load(f)

ds = lines()
with open('lotsalines.pickle', 'wb') as f:
    t = timeit.timeit(lambda: pickle.dump(ds, file=f, protocol=-1), number=1)
print('pickle.dump: {}'.format(t))

print('readlines:   {}'.format(timeit.timeit(lines, number=10))
print('pickle.load: {}'.format(timeit.timeit(pickles, number=10))

私の 'lotsalines.txt' ファイルは、655360 行、つまり 15532032 バイトになるまで複製されたソースです。

アップルパイソン 2.7.2:

readlines:   0.640027999878
pickle.load: 2.67698192596

そしてピクルファイルは19464748バイトです。

Python.org 3.3.0:

readlines:   1.5357899703085423
pickle.load: 1.5975534357130527

そして、それは 20906546 バイトです。

したがって、pickle少なくとも pickle プロトコル 3 を使用する場合、Python 3 は Python 2 よりもかなり高速化されていますが、単純な .xml ほど高速ではありませんreadlines。(そしてreadlines、3.x では非常に遅くなり、非推奨になりました。)

しかし実際には、パフォーマンスに懸念がある場合は、最初に が必要かどうかを検討する必要がありますlist。簡単なテストではlist、このサイズの を構築するコストは のほぼ半分であることが示されています ( 3.x でのreadlinesタイミング、2.x でのタイミング)。また、大量のメモリを使用します (これがおそらく実際に遅い理由でもあります)。実際には必要ない場合 (そして通常は必要ない場合) は、ファイルを反復処理して、必要な行を取得します。list(range(655360))list(xrange(655360))list

于 2013-02-15T19:16:18.303 に答える