InvokeとDynamicInvokeの違い


回答:


206

デリゲートインスタンスがある場合、正確なタイプを知っている場合もあれば、それがであることを知っている場合もあり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あなたが持っているすべてでない限り、常に望ましいDelegateobject[]

パフォーマンスを比較するために、デバッガー以外のリリースモード(コンソール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);

3
使用の場合、DynamicInvokeコンパイラーがデリゲート呼び出しを処理するためのより多くのILコードを生成することを意味しますか?
testCoder

2
@testCoderいいえ、リフレクションを使用します
Marc Gravell

@MarcGravellイベントを発生させているメソッドでこれを試すと、最初のメソッド呼び出しが約0,7766ミリ秒かかっていますが、2番目は0,0568ミリ秒かかっています。最初のものがInvokeの場合、DynamicInvokeよりも時間がかかります。逆の場合も同様です。私が1つのループであなたの例を試し、msを見てみたときInvoke: 0,0478ms, DynamicInvoke: 0,053ms。それらを複数のコールで比較するのはなぜですか?そして、なぜ最初の呼び出しは2番目の関数呼び出しよりも時間がかかるのですか?
uzay95 2016

4
@ uzay95メソッドの最初の呼び出しにより、JITコンパイルがCLRによって行われます。これは、プロセスの開始後に初めて呼び出されたすべてのメソッドに適用されます。この種のシナリオでは、3つのことの1つを行うことができます。(1)最初の呼び出しにかかった時間が最終結果で重要ではなくなるようにメソッドを数回実行する、(2)測定が完了するまで測定を開始しない'メソッドを1回呼び出したか、(3)ngen.exe(overkill)を使用しています。この投稿は、十分にそれを説明する... stackoverflow.com/questions/4446203/...を
クアンタ

@ marc-gravellメソッドのシグネチャはargsパラメータのparamsキーワードを示すため、DynamicInvokeに渡す配列を作成する必要はありません 。
zodo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.