|
Boost Users : |
Subject: Re: [Boost-users] finite state machine performance info
From: Franz Alt (f.alt_at_[hidden])
Date: 2009-11-27 03:37:44
I've already played with the Statechart library. I think it's a good
library but especially the fact that transitions take such a long time
isn't good in many situations like embedded systems for instance. Of
course Statechart has it's entitlement I think for you the new MSM
library (currently in review progress) is worth a look. State machines
build with MSM have very low overhead and are therefore very efficient.
I've taken a simple example to this mail. On my machine the state
machine with MSM is about 34 times faster than the one with Statechart.
Conoscenza Silente schrieb:
> Hi All
> Yesterday I started playing with Boost State Chart library
> implementing state machines for my applications.
> Each time I am moving into a new state I noticed that a new state is
> created; this means that the constructor of the
> boost::statechart::state class is called each time ( and the
> destructor for the state that I am leaving ).
>
> I would like to fasten up the whole process; let's say that I would
> like to avoid the creation/destruction of the class each time using
> object already allocated in memory that are deleted only at the exit
> of the application.
> Is this a good way in your opinion ?
>
> I saw that there is an allocator template argument but at the state
> where I am now I would lilke to not spend time in doing a new
> allocator for that: do you know if there already in place something
> that I can reuse for my purpose?
>
> Thanks CS
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/timer.hpp>
#include <boost/progress.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
using namespace boost::statechart;
namespace test_sc
{
struct state_1;
struct state_2;
struct state_3;
struct state_4;
struct main_machine :
state_machine<
main_machine,
state_1
// without allocator I have 5.6 seconds (used also in events)
//,boost::pool_allocator< main_machine > // with this
// allocator I go to 10 sec used also in events
//,boost::fast_pool_allocator< main_machine > // with this
//allocator I go to 8.7 sec
> {};
struct event_1_2 : event< event_1_2
//, boost::fast_pool_allocator< event_1_2 >
>{};
struct event_2_3 : event< event_2_3
//, boost::fast_pool_allocator< event_2_3 >
>{};
struct event_3_4 : event< event_3_4
//, boost::fast_pool_allocator< event_3_4 >
>{};
struct event_4_1 : event< event_4_1
//, boost::fast_pool_allocator< event_4_1 >
>{};
struct state_1
: simple_state< state_1, main_machine >
{
typedef transition< event_1_2, state_2 > reactions;
};
struct state_2
: simple_state< state_2, main_machine >
{
typedef transition< event_2_3, state_3 > reactions;
};
struct state_3
: simple_state< state_3, main_machine >
{
//typedef transition< event_3_4, state_4 > arc; // it doesn't work
typedef transition< event_3_4, state_4 > reactions;
//state_3(){std::cout<<"3";}
//~state_3(){std::cout<<"~3";}
};
struct state_4
: simple_state< state_4, main_machine >
{
typedef transition< event_4_1, state_1 > reactions;
};
}
namespace msm = boost::msm;
namespace mpl = boost::mpl;
namespace test_msm // Concrete FSM implementation
{
struct event_1_2 {};
struct event_2_3 {};
struct event_3_4 {};
struct event_4_1 {};
// Concrete FSM implementation
struct main_machine_ : public msm::front::state_machine_def<main_machine_>
{
// no need for exception handling or message queue
typedef int no_exception_thrown;
typedef int no_message_queue;
// The list of FSM states
struct state_1 : public msm::front::state<>
{
// optional entry/exit methods
//template <class Event,class FSM>
//void on_entry(Event const&,FSM& ) {std::cout << "entering: state_1" << std::endl;}
//template <class Event,class FSM>
//void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_1" << std::endl;}
};
struct state_2 : public msm::front::state<>
{
// optional entry/exit methods
//template <class Event,class FSM>
//void on_entry(Event const&,FSM& ) {std::cout << "entering: state_2" << std::endl;}
//template <class Event,class FSM>
//void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_2" << std::endl;}
};
struct state_3 : public msm::front::state<>
{
// optional entry/exit methods
//template <class Event,class FSM>
//void on_entry(Event const&,FSM& ) {std::cout << "entering: state_3" << std::endl;}
//template <class Event,class FSM>
//void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_3" << std::endl;}
};
struct state_4 : public msm::front::state<>
{
// optional entry/exit methods
//template <class Event,class FSM>
//void on_entry(Event const&,FSM& ) {std::cout << "entering: state_4" << std::endl;}
//template <class Event,class FSM>
//void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_4" << std::endl;}
};
// the initial state of the player SM. Must be defined
typedef state_1 initial_state;
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +---------+-------------+---------+---------------------+----------------------+
_row < state_1 , event_1_2 , state_2 >,
_row < state_2 , event_2_3 , state_3 >,
_row < state_3 , event_3_4 , state_4 >,
_row < state_4 , event_4_1 , state_1 >
// +---------+-------------+---------+---------------------+----------------------+
> {};
};
typedef msm::back::state_machine<main_machine_> main_machine;
}
void main(){
test_sc::main_machine fsm;
fsm.initiate();
{
boost::progress_timer t; // count the time elapsed
// before distruction: not very precise
// for expected big differences
for( int i = 0; i < 1000000; i ++ ){
fsm.process_event( test_sc::event_1_2() );
fsm.process_event( test_sc::event_2_3() );
fsm.process_event( test_sc::event_3_4() );
fsm.process_event( test_sc::event_4_1() );
}
}
test_msm::main_machine fsm2;
fsm2.start();
{
boost::progress_timer t; // count the time elapsed
// before distruction: not very precise
// for expected big differences
for( int i = 0; i < 1000000; i ++ ){
fsm2.process_event( test_msm::event_1_2() );
fsm2.process_event( test_msm::event_2_3() );
fsm2.process_event( test_msm::event_3_4() );
fsm2.process_event( test_msm::event_4_1() );
}
}
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net