[Mono-dev] Performance of Invoke

Jonathan Pryor jonpryor at vt.edu
Wed Jun 14 07:07:16 EDT 2006


I don't think that design is very good, for a number of reasons:

  - Performance will suck (due to reflection)
  - It's highly "magical" (due to reflection)
  - Documentation will likely be problematic (due to "magic")

A cleaner, faster, and more easily documented version would be this
(untested):

        //defined in class library
        class FsmEvent {}
        delegate void FsmEventHandler (object o, FsmEvent e);
        class Fsm
        {
            //events can be posted to the event queue and read from the 
            // dispatch loop from a thread...
            public Queue<fsmEvent>  QueueEvent;
        
            public event FsmEventHandler FsmEvent;
        
            public void dispatchEvent()
            {
                FsmEv e = Queue.Dequeue();
                FsmEvent (this, e);
            }
        }
        
        // defined in user library
        class UserFsmEvent : FsmEvent{}
        class FsmTimerEvent : FsmEvent{}
        
        class FsmUser
        {
            public void MyHandler (object o, FsmEvent e)
            {
                bool handled = false;
                if (!handled) handled = HandleUser (e as UserFsmEvent);
                if (!handled) handled = HandleTimer (e as
        FsmTimerEvent);
                if (!handled) {/* default behavior */}
            }
        
            private bool HandleUser (UserFsmEvent e)
            {
                if (e == null) return false;
                /* ... */
                return true;
            }
        
            private bool HandleTimer (UserFsmEvent e)
            {
                if (e == null) return false;
                /* ... */
                return true;
            }
        }

In short, use an event in Fsm to invoke a FsmEventHandler delegate,
which FsmUser.MyHandler matches.  FsmUser.MyHandler then uses normal
(fast!) type casting with `as' to delegate to the appropriate handler.

Sadly, this requires more work on the User's part, but (1) the work is
highly idiomatic, and (2) gives the user complete control, (3) allows
for saner behavior (less "magic"), and (4) provides excellent
performance.  (The only way to get better performance would be to use a
virtual function, and require that FsmUser inherit from Fsm and override
some virtual/abstract method declared within Fsm.)

If the above still doesn't work for you, you'd have to lookup a delegate
type from the FsmEvent type name, e.g. require that all *FsmEvent types
have a matching *FsmEventHandler delegate within the same assembly, then
use Reflection to lookup this *FsmEventHandler type and create an
appropriate delegate.

This won't help you much, though, unless you cache the delegate lookups
within Fsm; always re-looking up this information won't help performance
at all.

 - Jon

On Tue, 2006-06-13 at 22:06 -0500, Tim Michals wrote:
> I've tested on NET the performance of invoke compared to Delegate,
> Delegate 
> is several orders of magnitude faster.  The problem I'm having is
> creating a 
> delegate with the proper type, Delegate.CreateDelegate requires the
> delegate 
> type to be defined.  But the base library only knows the base type not
> the 
> class defined in the user code
> For example...(This is a very basic pseudo code)   Looking for better 
> perfomance then using Invoke..I read some methods of creating LCG but
> is 
> that the only way?
> 
> //defined in class library
> class fsmEvent{}
> class fsm
> {
>     //events can be posted to the event queue and read from the
> dispatch 
> loop from a thread...
>     public Queue<fsmEvent>  QueueEvent;
> 
>  public void dispatchEvent()
>  {
>   ....
>         fsmEv = Queue.dequeue();
>       Type t= userFsm.GetType();
>       MethodInfo mFsmEvent = t.GetMethod(  ... based on fsmEv type,
> match 
> the parameter list)
>     // invoke proper method
>       mFsmEvent.Invoke(userFsm,new
> object[]{ fsmLoop.fsmEventList[0]});
>    // Want to replace this is some type of Delegate for performance...
> 
>      }
> }
> 
> // define in user library
> class userFsmEvent : fsmEvent{}
> class fsmTimerEvent : fsmEvent{}
> 
> class fsmUser
> {
>     public void hander1(fsmEvent ev){}
>     public void handler2(fsmTimerEvent ev){}
>     public void hander3(userFsmEvent ev){}
> 
> }
> 
> 
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list




More information about the Mono-devel-list mailing list