When is not a good time to use python generators?

前端 未结 9 914
不思量自难忘°
不思量自难忘° 2020-11-27 10:27

This is rather the inverse of What can you use Python generator functions for?: python generators, generator expressions, and the itertools module are some of m

9条回答
  •  时光说笑
    2020-11-27 11:06

    Regarding performance: if using psyco, lists can be quite a bit faster than generators. In the example below, lists are almost 50% faster when using psyco.full()

    import psyco
    import time
    import cStringIO
    
    def time_func(func):
        """The amount of time it requires func to run"""
        start = time.clock()
        func()
        return time.clock() - start
    
    def fizzbuzz(num):
        """That algorithm we all know and love"""
        if not num % 3 and not num % 5:
            return "%d fizz buzz" % num
        elif not num % 3:
            return "%d fizz" % num
        elif not num % 5:
            return "%d buzz" % num
        return None
    
    def with_list(num):
        """Try getting fizzbuzz with a list comprehension and range"""
        out = cStringIO.StringIO()
        for fibby in [fizzbuzz(x) for x in range(1, num) if fizzbuzz(x)]:
            print >> out, fibby
        return out.getvalue()
    
    def with_genx(num):
        """Try getting fizzbuzz with generator expression and xrange"""
        out = cStringIO.StringIO()
        for fibby in (fizzbuzz(x) for x in xrange(1, num) if fizzbuzz(x)):
            print >> out, fibby
        return out.getvalue()
    
    def main():
        """
        Test speed of generator expressions versus list comprehensions,
        with and without psyco.
        """
    
        #our variables
        nums = [10000, 100000]
        funcs = [with_list, with_genx]
    
        #  try without psyco 1st
        print "without psyco"
        for num in nums:
            print "  number:", num
            for func in funcs:
                print func.__name__, time_func(lambda : func(num)), "seconds"
            print
    
        #  now with psyco
        print "with psyco"
        psyco.full()
        for num in nums:
            print "  number:", num
            for func in funcs:
                print func.__name__, time_func(lambda : func(num)), "seconds"
            print
    
    if __name__ == "__main__":
        main()
    

    Results:

    without psyco
      number: 10000
    with_list 0.0519102208309 seconds
    with_genx 0.0535933367509 seconds
    
      number: 100000
    with_list 0.542204280744 seconds
    with_genx 0.557837353115 seconds
    
    with psyco
      number: 10000
    with_list 0.0286369007033 seconds
    with_genx 0.0513424889137 seconds
    
      number: 100000
    with_list 0.335414877839 seconds
    with_genx 0.580363490491 seconds
    

提交回复
热议问题