Fredrik Lundh wrote: > Carl Cerecke wrote: > > >>It turns out that generators are more efficient than the eval function >>excuting bits of compiled code. About 20-25% faster. > > > why are you using generators to return things from a function, when > you can just return the things ?
Trying to find the fastest way to implement finite state machine. The included file times 4 different ways, with functions the fastest. The reason, I think, for the unusual sequence if id()s of the generators - see grandparent post - (and the reason for their poor performance compared to functions), is because the reference to the generator is being lost, then another generator is being created with the same id. Properly done, I would expect generators to out perform functions. These are the numbers I get on a P3 600: $ ./foo.py action generator overhead: 13.25 --- exec: 8.7 --- eval: 10.09 --- generators: 6.68 --- functions: 3.37 #!/usr/bin/env python import time s_on = compile(''' #print 'on' action = next_action() if action == 'lift': state = s_on elif action == 'push': state = s_off else: state = None ''','','exec') s_off = compile(''' #print 'off' action = next_action() if action == 'lift': state = s_on elif action == 'push': state = s_off else: state = None ''','','exec') def f_on(): action = next_action() if action == 'lift': return f_on elif action == 'push': return f_off else: return None def f_off(): action = next_action() if action == 'lift': return f_on elif action == 'push': return f_off else: return None def g_on(): #print "on" action = next_action() if action == 'lift': yield g_on() elif action == 'push': yield g_off() else: yield None def g_off(): #print "off" action = next_action() if action == 'lift': yield g_on() elif action == 'push': yield g_off() else: yield None def actions(n): import random for i in range(n-1): yield random.choice(['lift','push']) yield None r = 1000000 #r = 10 next_action = actions(r).next a = time.clock() while next_action(): pass z = time.clock() print "action generator overhead:",z-a common = z-a print "---" next_action = actions(r).next state = s_on # start state a = time.clock() while state: exec state z = time.clock() print "exec:",z-a-common print "---" next_action = actions(r).next state = s_on # start state a = time.clock() while state: eval(state) z = time.clock() print "eval:",z-a-common print "---" next_action = actions(r).next s_g_on = g_on() s_g_off = g_off() state = s_g_on a = time.clock() while state: #print id(state) state = state.next() z = time.clock() print "generators:",z-a-common print "---" next_action = actions(r).next state = f_on a = time.clock() while state: state = state() z = time.clock() print "functions:",z-a-common -- http://mail.python.org/mailman/listinfo/python-list