[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