Так что я сделал несколько измерений на этом.
var delegates = new List<Delegate>();
var actions = new List<Action<object>>();
const int dataCount = 100;
const int loopCount = 10000;
for (int i = 0; i < dataCount; i++)
{
Action<int> a = d => { };
delegates.Add(a);
actions.Add(o => a((int)o));
}
var sw = Stopwatch.StartNew();
for (int i = 0; i < loopCount; i++)
{
foreach (var action in actions)
action(i);
}
Console.Out.WriteLine("{0:#,##0} Action<object> calls in {1:#,##0.###} ms",
loopCount * dataCount, sw.Elapsed.TotalMilliseconds);
sw = Stopwatch.StartNew();
for (int i = 0; i < loopCount; i++)
{
foreach (var del in delegates)
del.DynamicInvoke(i);
}
Console.Out.WriteLine("{0:#,##0} DynamicInvoke calls in {1:#,##0.###} ms",
loopCount * dataCount, sw.Elapsed.TotalMilliseconds);
Я создал несколько элементов для косвенного вызова, чтобы избежать какой-либо оптимизации, которую может выполнить JIT.
Результаты весьма убедительны!
1,000,000 Action calls in 47.172 ms
1,000,000 Delegate.DynamicInvoke calls in 12,035.943 ms
1,000,000 Action calls in 44.686 ms
1,000,000 Delegate.DynamicInvoke calls in 12,318.846 ms
Таким образом, в этом случае замена на DynamicInvoke
дополнительного косвенного вызова и приведение была примерно в 270 раз быстрее . Всего за день работы.