最近我在Jon Clements的帮助下发现了this线程,下面的代码执行时间非常不同。为什么遍历枚举比发生器快得多?
你知道为什么会发生这种情况吗?
评论: self.stream_data是一个具有许多零和int16值的向量元组,create_ZS_data方法执行所谓的ZeroSuppression。
环境
输入:许多(3.5K)小文件(〜120KB每)
OS: LINUX64
的Python版本2.6.8
解决方案基于发电机:
def create_ZS_data(self):
self.ZS_data = ([column, row, self.stream_data[column + row * self.rows ]]
for row, column in itertools.product(xrange(self.rows), xrange(self.columns))
if self.stream_data[column + row * self.rows ])
探查信息:
ncalls tottime percall cumtime percall filename:lineno(function)
3257 1.117 0.000 71.598 0.022 decode_from_merlin.py:302(create_ZS_file)
463419 67.705 0.000 67.705 0.000 decode_from_merlin.py:86(<genexpr>)
乔恩的解决方案:
create_ZS_data(self):
self.ZS_data = list()
for rowno, cols in enumerate(self.stream_data[i:i+self.columns] for i in xrange(0, len(self.stream_data), self.columns)):
for colno, col in enumerate(cols):
# col == value, (rowno, colno) = index
if col:
self.ZS_data.append([colno, rowno, col])
探查信息:
ncalls tottime percall cumtime percall filename:lineno(function)
3257 18.616 0.006 19.919 0.006 decode_from_merlin.py:83(create_ZS_data)
看起来相当明显,它与第一个解决方案中的呼叫次数有关,不是吗? – martineau 2012-07-23 11:21:51
是的,但不是生来处理大量呼叫的生成器?他们通常被推荐为大列表的替代品。 – Michal 2012-07-23 11:28:14
对于简单情况,生成器*通常*以CPU为代价减少内存使用量。 – Hamish 2012-07-23 11:36:59