gpt4 book ai didi

python - 为什么这个 Fizz Buzz 生成器比这个 Fizz Buzz Iterator 类快得多?

转载 作者:太空狗 更新时间:2023-10-29 18:34:18 27 4
gpt4 key购买 nike

在学习了迭代器类方法和生成器之后,我测试了使用每个习语的简单 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

根据 timeit,生成器函数比迭代器类快 1¾ 倍

我的问题又来了:为什么这个 Fizz Buzz 生成器比这个 Fizz Buzz Iterator 类快得多?

Fizz Buzz 迭代器类

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)

Fizz Buzz 发生器函数

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)

最佳答案

因为显然,生成器的实现比迭代器更有效。

您的第一个解决方案具有以下有趣的特征:

  1. 它使用对象。
  2. 对于 n 个数字的迭代,调用了 3 + n 个方法并访问了 2 + 4·n 个属性,它们都是可能会导致操作缓慢。
  3. 异常用于控制流程。

第二种解决方案不执行任何这些操作,而是 yield,这意味着语言运行时会执行繁重的工作。由于运行时通常用 C 语言实现,因此这比您的第一个解决方案的非常高级的代码优化得多。

接下来,您应该考虑您实际进行基准测试的内容。为了获得良好的基准,您应该选择不同的输入大小 n 并观察两种解决方案在不同规模下的比较情况。

  • 对于非常小的n,我们预计初始化成本占主导地位。这与您的结果一致,因为执行函数调用比创建对象的成本更低。
  • 对于较大的 n,我们期望算法的特征占主导地位。由于算法完全相同,因此图形应该具有相同的形状。但是每次迭代,第一个解决方案的成本要高得多(四个属性访问,一个方法调用)。这两个解决方案将是斜率略有不同的图形。每次迭代成本的确切关系只能通过为许多输入大小 n 获取包含许多时间的大型数据集,然后将函数拟合到该数据来评估。

关于python - 为什么这个 Fizz Buzz 生成器比这个 Fizz Buzz Iterator 类快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21650038/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com