我有一个用例,我需要从文件中的行构建一个列表。此操作将在分布式网络上执行100次。我一直在使用明显的解决方案:
with open("file.txt") as f:
ds = f.readlines()
我只是想到,或许我最好创建一次这个列表,将其腌制成文件,然后使用该文件取消每个节点上的数据。
如果我这样做会增加性能吗?
答案 0 :(得分: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字节。
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
- 通常你不会 - 只是遍历文件,在需要时获取行。