2012-10-12 11 views

risposta

160

Quando si dispone di un'istanza delegata, è possibile conoscere il tipo esatto oppure si potrebbe semplicemente sapere che è uno Delegate. Se si conosce il tipo esatto, è possibile utilizzare Invoke, che è molto veloce - tutto è già pre-convalidato. Ad esempio:

Func<int,int> twice = x => x * 2; 
int i = 3; 
int j = twice.Invoke(i); 
// or just: 
int j = twice(i); 

Tuttavia! Se sai solo che è Delegate, deve risolvere manualmente i parametri etc - questo potrebbe comportare unboxing, ecc. - si sta riflettendo molto. Per esempio:

Delegate slowTwice = twice; // this is still the same delegate instance 
object[] args = { i }; 
object result = slowTwice.DynamicInvoke(args); 

nota che ho scritto la lunga mano args mettere in chiaro che un object[] è coinvolto. Ci sono un sacco di costi aggiuntivi qui:

  • matrice
  • convalidare gli argomenti passati sono un "fit" per l'attuale MethodInfo
  • unboxing ecc come necessario
  • riflessione-richiamare
  • poi il il chiamante deve fare qualcosa per elaborare il valore di ritorno

In pratica, evitare DynamicInvoke ogni volta y puoi. Invoke è sempre preferibile, a meno che tutto quello che hai è uno Delegate e uno object[].

Per un confronto delle prestazioni, il seguente nella modalità di rilascio al di fuori del debugger (un exe console) stampe:

Invoke: 19ms 
DynamicInvoke: 3813ms 

Codice:

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

Vuol dire che in caso di utilizzo del DynamicInvoke il compilatore produce più codice IL per gestire l'invocazione del delegato? – testCoder

+1

@testCoder no, verrà utilizzata la riflessione –

+2

Grazie, spiegazione molto completa. – testCoder