一般来说,yield和append哪个更快?
我现在正在做一个个人学习项目,主要是读取一个XML数据库。我发现自己在写一些函数来收集数据,但不太确定用什么方法返回这些数据会比较快。
一般来说,哪种方式更快呢:
yield
,还是- 在函数内部用好几个
append()
,然后再return
返回一个列表?
我很想知道在什么情况下yield
会比append()
快,或者反过来。
5 个回答
6
有一种比TH4Ck的yielding()更快的方法,那就是列表推导。
In [245]: def list_comp():
.....: return [d for d in data]
.....:
In [246]: timeit yielding()
10000 loops, best of 3: 89 us per loop
In [247]: timeit list_comp()
10000 loops, best of 3: 63.4 us per loop
当然,在不了解你代码结构的情况下去微观测试这些操作是有点傻的。它们各自在不同的情况下都有用。例如,列表推导适合用来执行一些简单的操作,这些操作可以用一句话表达。而yield的一个重要优点是可以把遍历的代码放到一个生成器方法里。到底用哪个,主要还是看你具体的使用场景。
10
我最近也在思考一个类似的问题,想找出生成一个列表(或元组)所有排列的方法,可以通过把结果加到一个列表里或者用生成器来实现。经过我的测试(以长度为9的排列为例,大约需要一秒钟左右生成),我发现:
- 最简单的方法(排列是列表,添加到列表中,返回一个列表的列表)大约需要的时间是
itertools.permutations
的三倍。 - 使用生成器(也就是用
yield
)可以把时间减少大约20%。 - 使用生成器并生成元组是最快的,大约是
itertools.permutations
所需时间的两倍。
不过要注意,这些结果要谨慎看待!时间测量和性能分析非常有用:
if __name__ == '__main__':
import cProfile
cProfile.run("main()")
25
yield
的一个大优点是它是 懒惰的,而且速度通常不是使用它的 最佳 理由。但如果在你的情况下它能正常工作,那就没有理由不使用它:
# yield_vs_append.py
data = range(1000)
def yielding():
def yielder():
for d in data:
yield d
return list(yielder())
def appending():
lst = []
for d in data:
lst.append(d)
return lst
这是结果:
python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "yielding()"
10000 loops, best of 3: 80.1 usec per loop
python2.7 -m timeit -s "from yield_vs_append import yielding,appending" "appending()"
10000 loops, best of 3: 130 usec per loop
至少在这个非常简单的测试中,yield
的速度比 append 更快。