回答:
デリゲートインスタンスがある場合、正確なタイプを知っている場合もあれば、それがであることを知っている場合もあり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
あなたが持っているすべてでない限り、常に望ましい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);
Invoke: 0,0478ms, DynamicInvoke: 0,053ms
。それらを複数のコールで比較するのはなぜですか?そして、なぜ最初の呼び出しは2番目の関数呼び出しよりも時間がかかるのですか?