Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the performance of c# delegate creation

My project involved a lot of reflection. So, I cached delegates in dictionaries. The problem is that I chose to use MethodInfo as dict keys, I've tried to use a look-up method, which is something like this:

Func<T,R> LookUp(Func<T,R> m)
{
  return (Func<T,R>)dict[m.Method];
}
//LookUp(MyCls.Method)

But, after doing some tests, I found out that feeding the LookUp method with a function address, i.e, creating transitional delegates on the fly, is kinda slow,very slow indeed:

class MyCls
{
    public static void Operate(int whatever){ }
}

class MainClass
{
    delegate void Doer<T>(T arg);
    static Dictionary<MethodInfo,Delegate> _dict = new Dictionary<MethodInfo,Delegate>();

public static void Main (string[] args)
    {
        Action<int> dg = MyCls.Operate;
        _dict[dg.Method] = Delegate.CreateDelegate(typeof(Action<int>),dg.Method);

        //performance test
        var start = Environment.TickCount;          
        for (int i = 0; i < 10000000; i++)
        {
            //LookUp(dg);//11               
            //LookUp<int>(MyCls.Operate);//1503
            //new MyCls();//431
        }

        Console.WriteLine (Environment.TickCount-start);
    }
    static  Action<T> LookUp<T>(Action<T> dg) 
    {
        //should return (Action<T>)_dict[dg.Method];
        return null;
    }

So, the question is: To improve the performance, should I change my approach, and write some unsafe code (Are function pointers even supported by c#?) or is there alternative c#-style solutions for this kind of situations?

Please, help me out of there!

like image 972
Need4Steed Avatar asked Jul 28 '11 03:07

Need4Steed


People also ask

What makes C so powerful?

C is one of the most powerful "modern" programming language, in that it allows direct access to memory and many "low level" computer operations. C source code is compiled into stand-a-lone executable programs.

Why C is efficient and fast?

But to answer your question, well-written C code will generally run faster than well-written code in other languages because part of writing C code "well" includes doing manual optimizations at a near-machine level.

Why is C very important?

C is very fast in terms of execution time. Programs written and compiled in C execute much faster than compared to any other programming language. C programming language is very fast in terms of execution as it does not have any additional processing overheads such as garbage collection or preventing memory leaks etc.


1 Answers

I used a class some time ago for event aggregation (Mediator) in a Winform application that had a dictionary cache of Type as key and Delegate as Value. The class looks something like...

public sealed class EventAggregator
    {
        #region Fields

        private readonly Dictionary<Type, List<Object>> subscribers = new Dictionary<Type, List<Object>>();

        #endregion

        #region Public Methods

        public void Subscribe<TMessage>(Action<TMessage> handler)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                handlers.Add(handler);
            }
            else
            {
                var handlers = new List<Object> {handler};
                subscribers[typeof(TMessage)] = handlers;
            }
        }

        public void Unsubscribe<TMessage>(Action<TMessage> handler)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                handlers.Remove(handler);

                if (handlers.Count == 0)
                {
                    subscribers.Remove(typeof(TMessage));
                }
            }
        }

        public void Publish<TMessage>(TMessage message)
        {
            if (subscribers.ContainsKey(typeof(TMessage)))
            {
                var handlers = subscribers[typeof(TMessage)];
                foreach (Action<TMessage> handler in handlers)
                {
                    handler.Invoke(message);
                }
            }
        }

        #endregion
    }

which i guess is somewhat similar to what you are trying to do.

Instead of looking up on the delegate itself, try looking up on the type which that delegate is required for.

like image 66
Raghu Avatar answered Nov 04 '22 23:11

Raghu