通过调用readlines()取消拾取数据结构Vs.build



我有一个用例,需要从文件中的行构建一个列表。此操作可能在分布式网络上执行100次。我一直在使用显而易见的解决方案:

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

我只是有一个想法,也许我最好创建一次这个列表,将其pickle到一个文件中,然后使用该文件来取消pickle每个节点上的数据。

如果我这样做,性能会提高吗?

如果我这样做,性能会提高吗?

试试看!

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字节。

Apple Python 2.7.2:

readlines:   0.640027999878
pickle.load: 2.67698192596

pickle文件为19464748字节。

Python.org 3.3.0:

readlines:   1.5357899703085423
pickle.load: 1.5975534357130527

它是20906546字节。

因此,Python 3比Python 2大大加快了pickle的速度,至少如果您使用pickle协议3,但它仍然远不及简单的readlines。(readlines在3.x中的速度慢了很多,同时也被弃用。)

但实际上,如果您有性能问题,您应该首先考虑是否需要list。快速测试表明,构建这样大小的list几乎是readlines的一半成本(3.x中为list(range(655360))计时,2.x中为list(xrange(655360))计时)。而且它需要大量内存(这可能也是它速度慢的原因)。如果您实际上并不需要list——通常也不需要——只需对文件进行迭代,根据需要获取行。

最新更新