[英]Why is this Fizz Buzz generator significantly faster than this Fizz Buzz Iterator class?
After learning about iterator class methods and generators, I tested the performance characteristics of simple Fizz Buzz solutions utilizing each idiom: 在了解了迭代器类的方法和生成器之后,我使用每种习语测试了简单的Fizz Buzz解决方案的性能特征:
>>> from timeit import timeit
>>> timeit('tuple(fizzbuzz.FizzBuzzIterator(10))', 'import fizzbuzz')
13.281935930252075
>>> timeit('tuple(fizzbuzz.fizz_buzz_generator(10))', 'import fizzbuzz')
7.619534015655518
According to timeit
the generator function is about 1¾ times faster than the iterator class. 据
timeit
发电机功能比iterator类快了约1.75倍 。
My question again: Why is this Fizz Buzz generator significantly faster than this Fizz Buzz Iterator class? 再问我一个问题:为什么这个Fizz Buzz生成器比这个Fizz Buzz Iterator类快得多?
class FizzBuzzIterator:
def __init__(self, low, high=None):
if high is None:
self.high = low
self.current = 1
else:
self.high = high
self.current = max(low, 1)
def __iter__(self):
return self
def next(self):
if self.current > self.high:
raise StopIteration
else:
c = self.current
self.current += 1
if (c % 5 + c % 3) == 0:
return 'FizzBuzz'
elif c % 5 == 0:
return 'Buzz'
elif c % 3 == 0:
return 'Fizz'
else:
return str(c)
def fizz_buzz_generator(low, high=None):
if high is None:
high = low
cur = 1
else:
cur = max(low, 1)
while cur <= high:
c = cur
cur += 1
if (c % 5 + c % 3) == 0:
yield 'FizzBuzz'
elif c % 5 == 0:
yield 'Buzz'
elif c % 3 == 0:
yield 'Fizz'
else:
yield str(c)
Because apparently, generators are implemented more efficiently than iterators. 因为显然,生成器比迭代器更有效地实现。
Your first solution has the following interesting characteristics: 您的第一个解决方案具有以下有趣的特征:
The second solution does none of these, instead it yield
s which means that the language runtime performs the heavy lifting. 第二种解决方案不执行任何操作,而是
yield
s,这意味着语言运行库会执行繁重的工作。 As the runtime is usually implemented in C, this can be far more optimized than the very high-level code of your first solution. 由于运行时通常是用C实现的,因此与第一个解决方案的高级代码相比,它的优化程度更高。
Next, you should consider what you are actually benchmarking. 接下来,你应该考虑您实际基准。 For a good benchmark you should choose different input sizes n and watch how the two solutions compare at different scales.
为了获得良好的基准,您应该选择不同的输入大小n,并观察两种解决方案在不同规模下的比较情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.