Ответы:
Если у вас есть экземпляр делегата, вы можете знать точный тип или просто знать, что это Delegate
. Если вы знаете точный тип, вы можете использовать Invoke
, что очень быстро - все уже предварительно проверено. Например:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
Тем не мение! Если вы просто знаете, что это так Delegate
, он должен разрешить параметры и т. Д. Вручную - это может включать распаковку и т. Д. - происходит много размышлений. Например:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
Обратите внимание: я написал args
длинную руку, чтобы прояснить, что object[]
задействован. Здесь много дополнительных затрат:
MethodInfo
По сути, избегайте, DynamicInvoke
когда можете. Invoke
всегда предпочтительнее, если все, что у вас есть, - это a Delegate
и an object[]
.
Для сравнения производительности в режиме выпуска вне отладчика (консольный exe) печатается следующее:
Invoke: 19ms
DynamicInvoke: 3813ms
Код:
Func<int,int> twice = x => x * 2;
const int LOOP = 5000000; // 5M
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
twice.Invoke(3);
}
watch.Stop();
Console.WriteLine("Invoke: {0}ms", watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
twice.DynamicInvoke(3);
}
watch.Stop();
Console.WriteLine("DynamicInvoke: {0}ms", watch.ElapsedMilliseconds);
Invoke: 0,0478ms, DynamicInvoke: 0,053ms
. Почему вы сравниваете их больше 1 звонка? И почему первый вызов функции занимает больше времени, чем второй?