[Mono-dev] Performance of Invoke

Tim Michals tcmichals at msn.com
Wed Jun 14 07:53:35 EDT 2006


The goal is to provide a polymorphic functions or delegates based on the 
type of data being past.  Yes, you are correct, this is what I have 
currently but the fsmEvent function has a switch statement decoding the 
type.  In the code I provided, I do have cache of functions, methodInfo etc 
in a tree to assist performance.

----- Original Message ----- 
From: "Jonathan Pryor" <jonpryor at vt.edu>
To: "Tim Michals" <tcmichals at msn.com>
Cc: "mono-devel" <mono-devel-list at lists.ximian.com>
Sent: Wednesday, June 14, 2006 6:07 AM
Subject: Re: [Mono-dev] Performance of Invoke


>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