On Wed, 25 Jan 2006 12:33:17 +1300, Carl Cerecke <[EMAIL PROTECTED]> wrote:

>Adding a continue statemtent after the yield statements yields :-) a 
>speed increase. Still not as good as functions though. (about 30% slower)
>
>Cheers,
>Carl
>
>Carl Cerecke wrote:
>> Carl Cerecke wrote:
>> Generator FSM done properly (well, better anyway). They are still almost 
>> twice as slow as plain function calls, though.
>> 
<snip>
I think I would use a generator to do state transitions, but make the state
external, or at least the part that's interesting to the outside world.

In this peculiar example the transition rules are the same for both states,
so you only need one implementation of the logic. So the example is not so nice.


 >>> def fsm(state, events):
 ...     for action in events:
 ...         if action == 'lift': state.name = 'ON'
 ...         elif action == 'push': state.name = 'OFF'
 ...         else:
 ...             state.name = 'END'
 ...             break
 ...         yield state
 ...
 >>> def actions(n):
 ...     import random
 ...     return iter([random.choice(['lift','push']) for i in range(n-1)] + 
[None])
 ...
 >>> class State(object): pass
 ...
 >>> def test(r=1000000):
 ...     state = State()
 ...     state.name = 'ON'
 ...     from time import clock
 ...     t0 = clock()
 ...     for state in fsm(state, actions(r)): pass
 ...     t1 = clock()
 ...     print '%12.6f'%((t1-t0)/r)
 ...
 >>> test(1000)
     0.000058
 >>> test(1000)
     0.000032
 >>> test(1000)
     0.000032
 >>> test(100000)
     0.000032
 >>> a = list(actions(10))
 >>> a
 ['lift', 'push', 'push', 'lift', 'push', 'lift', 'push', 'lift', 'lift', None]
 >>> state = State()
 >>> state.name = 'START'
 >>> f = fsm(state, a)
 >>> for state in f: print state.name,
 ...
 ON OFF OFF ON OFF ON OFF ON ON
 >>>
 
Obviously you can keep state in the fsm generator by placing yields in 
different places and
looping in different ways, but always storing the externally interesting state 
as attributes
of the state parameter and yielding that to tell the world the latest. Since 
only attributes
are being modified, the original state binding could be used and the 
generator's yielded
value could be ignored, but it could be handy if the generator is passed around 
IWT.

The world could also feed info in as attributes of state. And other generators 
could share
the same external state variable and all kinds of weird things could be built 
;-)

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to