简体   繁体   English

Python生成器timeit

[英]Python generators timeit

I am trying to understand Python generators in many tutorials guys tells that they are much faster then for example iterating through a list, so I give it a try, I wrote a simple code. 我试图理解许多教程中的Python生成器,而这些教程告诉他们它们比例如遍历列表要快得多,所以我尝试一下,编写了一个简单的代码。 I didn't expect that time difference can be that big, can someone explain me why? 我没想到时差会那么大,有人能解释我为什么吗? Or maybe I am doing something wrong here. 也许我在这里做错了。

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()

Results: t = 0.565694382945 t1 =11.9298217371 结果:t = 0.565694382945 t1 = 11.9298217371

You are not comparing f and f1 fairly. 您没有公平地比较ff1

Your first test is only measuring how long it takes Python to construct a generator object. 您的第一个测试只是测量Python 构造生成器对象所花费的时间。 It never iterates over this object though, which means the code inside f is never actually executed (generators only execute their code when they are iterated over). 但是,它永远不会迭代该对象,这意味着f内的代码永远不会实际执行(生成器仅在对其进行迭代时才执行其代码)。

Your second test however measures how long it takes to call f1 . 但是,您的第二项测试将测量调用f1所需的时间。 Meaning, it counts how long it takes the function to construct the list l , run the for-loop to completion, call list.append numerous times, and then return the result. 意思是,它计算函数构造列表l ,运行for循环直至完成,调用list.append多次,然后返回结果。 Obviously, this will be much slower than just producing a generator object. 显然,这将比仅生成生成器对象慢得多。

For a fair comparison, exhaust the generator f by converting it into a list: 为了公平起见,将生成器f转换为列表以使其耗尽:

t = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f")

This will cause it to be iterated over entirely, which means the code inside f will now be executed. 这将导致它被完全迭代,这意味着f的代码现在将被执行。

You're timing how long it takes to create a generator object. 您正在计时创建生成器对象所需的时间。 Creating one doesn't actually execute any code, so you're essentially timing an elaborate way to do nothing. 创建一个代码实际上并不会执行任何代码,因此实际上您正在计时一种精心设计的不执行任何操作的方法。

After you fix that, you'll find that generators are usually slightly slower when run to completion. 修复此问题后,您会发现生成器运行完成时通常会稍微慢一些。 Their advantage is that they don't need to store all elements in memory at once, and can stop halfway through. 它们的优势在于,它们不需要一次将所有元素存储在内存中,并且可以中途停止。 For example, when you have a sequence of boolean values and want to check whether any of them are true, with lists you'd first compute all the values and create a list of them, before checking for truth, while with generators you can: 例如,当您有一系列布尔值并且要检查它们是否为真时,使用列表时,首先要计算所有值并创建它们的列表,然后再检查真值,而使用生成器时,您可以:

  • Create the first boolean 创建第一个布尔值
  • Check if it's true, and if so, stop creating booleans 检查是否为真,如果是,则停止创建布尔值
  • Else, create the second boolean 否则,创建第二个布尔值
  • Check if that one's true, and if so, stop creating booleans 检查一个人是否正确,如果是,请停止创建布尔值
  • And so on. 等等。

https://wiki.python.org/moin/Generators has some good information under the section improved performance. https://wiki.python.org/moin/Generators在“提高性能”部分下有一些不错的信息。 Although creating a generator can take a bit of time, it offers a number of advantages. 尽管创建一个生成器可能会花费一些时间,但它具有许多优点。

  • Uses less memory. 使用更少的内存。 By creating the values one by one, the whole list is never in memory. 通过一一创建值,整个列表就永远不会在内存中。
  • Less time to begin. 开始的时间更少。 Making a whole list takes time, while a generator can be used as soon as it creates the first value. 制作整个列表需要花费时间,而生成器可以在创建第一个值后立即使用。
  • Generators don't have a set ending point. 生成器没有设定的终点。

Here's a good tutorial on creating generators and iterators http://sahandsaba.com/python-iterators-generators.html . 这是一个有关创建生成器和迭代器的好教程, 网址为http://sahandsaba.com/python-iterators-generators.html Check it out! 看看这个!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM