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!
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With