1 ответ:
когда у вас есть экземпляр делегата, вы можете узнать точный тип, или вы можете просто знать, что это
Delegate. Если вы знаете точный тип, вы можете использоватьInvoke, которая составляет очень быстро - все уже предварительно проверены. Например:это. Есть много дополнительных расходов здесь:Func<int,int> twice = x => x * 2; int i = 3; int j = twice.Invoke(i); // or just: int j = twice(i);
- массив
- проверка переданных аргументов является "подходящим" для фактического
MethodInfo- распаковка и т. д. По мере необходимости
- reflection-invoke
- тогда вызывающий должен что-то сделать, чтобы обработать возвращаемое значение
в принципе, избежать
DynamicInvokeкогда-нибудь вы можете.Invokeвсегда предпочтительнее, если все у вас естьDelegateи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);
Comments