首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个Fizz Buzz生成器比这个Fizz Buzz Iterator类要快得多?

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

Stack Overflow用户
提问于 2014-02-08 17:57:14
回答 1查看 2.9K关注 0票数 10

在学习了迭代器类方法和生成器之后,我使用以下每个成语测试了简单Fizz Buzz解决方案的性能特性:

代码语言:javascript
复制
>>> 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倍于1。

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

Fizz迭代器类

代码语言:javascript
复制
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发生器函数

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-08 18:24:26

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

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

  1. 它使用物体。
  2. 对于n个数上的迭代,调用3+n方法,访问2+ 4·n属性,这都是潜在的慢操作。
  3. 异常用于控制流。

第二个解决方案不执行这些操作,而是使用yield,这意味着语言运行库执行繁重的任务。由于运行时通常是用C实现的,这可以比第一个解决方案的非常高级别的代码更优化。

接下来,你应该考虑一下你实际上在做的是什么。对于一个好的基准测试,您应该选择不同的输入大小n,并观察这两种解决方案如何在不同的尺度上进行比较。

  • 对于极小的n,我们预计非零化成本将占主导地位。这与您的结果是一致的,因为执行函数调用比创建对象花费更少。
  • 对于较大的n,我们期望该算法的特征占主导地位。由于算法是完全相同的,所以图应该具有相同的形状。但是每次迭代,第一个解决方案的成本要高得多(四个属性访问,一个方法调用)。然后,这两个解将是具有稍微不同的斜率的图。每一次迭代成本的精确关系只能通过获得多个输入大小n的多个时间的大数据集,然后拟合该数据的函数来评估。
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21650038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档