[英]Python generators timeit
我试图理解许多教程中的Python生成器,而这些教程告诉他们它们比例如遍历列表要快得多,所以我尝试一下,编写了一个简单的代码。 我没想到时差会那么大,有人能解释我为什么吗? 也许我在这里做错了。
def f(limit):
for i in range(limit):
if(i / 7.0) % 1 == 0:
yield i
def f1(limit):
l = []
for i in range(limit):
if(i / 7.0) % 1 == 0:
l.append(i)
return l
t = timeit.Timer(stmt="f(50)", setup="from __main__ import f")
print t.timeit()
t1 = timeit.Timer(stmt="f1(50)", setup="from __main__ import f1")
print t1.timeit()
结果:t = 0.565694382945 t1 = 11.9298217371
您没有公平地比较f
和f1
。
您的第一个测试只是测量Python 构造生成器对象所花费的时间。 但是,它永远不会迭代该对象,这意味着f
内的代码永远不会实际执行(生成器仅在对其进行迭代时才执行其代码)。
但是,您的第二项测试将测量调用f1
所需的时间。 意思是,它计算函数构造列表l
,运行for循环直至完成,调用list.append
多次,然后返回结果。 显然,这将比仅生成生成器对象慢得多。
为了公平起见,将生成器f
转换为列表以使其耗尽:
t = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f")
这将导致它被完全迭代,这意味着f
的代码现在将被执行。
您正在计时创建生成器对象所需的时间。 创建一个代码实际上并不会执行任何代码,因此实际上您正在计时一种精心设计的不执行任何操作的方法。
修复此问题后,您会发现生成器运行完成时通常会稍微慢一些。 它们的优势在于,它们不需要一次将所有元素存储在内存中,并且可以中途停止。 例如,当您有一系列布尔值并且要检查它们是否为真时,使用列表时,首先要计算所有值并创建它们的列表,然后再检查真值,而使用生成器时,您可以:
https://wiki.python.org/moin/Generators在“提高性能”部分下有一些不错的信息。 尽管创建一个生成器可能会花费一些时间,但它具有许多优点。
这是一个有关创建生成器和迭代器的好教程, 网址为http://sahandsaba.com/python-iterators-generators.html 。 看看这个!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.