After learning about iterator class methods and generators, I tested the performance characteristics of simple Fizz Buzz solutions utilizing each idiom:
>>> 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.
My question again: Why is this Fizz Buzz generator significantly faster than this Fizz Buzz Iterator class?
Fizz Buzz iterator class
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 generator function
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)