Jawaban:
Ketika Anda memiliki instance delegasi, Anda mungkin tahu tipe yang tepat, atau Anda mungkin tahu itu adalah Delegate
. Jika Anda tahu jenis pastinya, Anda bisa menggunakannya Invoke
, yang sangat cepat - semuanya sudah divalidasi sebelumnya. Sebagai contoh:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
Namun! Jika Anda hanya tahu Delegate
, itu harus menyelesaikan parameter dll secara manual - ini mungkin melibatkan unboxing, dll - banyak refleksi terjadi. Sebagai contoh:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
Catatan Saya sudah menulis args
tangan panjang untuk memperjelas bahwa ada object[]
yang terlibat. Ada banyak biaya tambahan di sini:
MethodInfo
Pada dasarnya, hindari DynamicInvoke
kapan saja Anda bisa. Invoke
selalu lebih disukai, kecuali yang Anda miliki adalah a Delegate
dan a object[]
.
Untuk perbandingan kinerja, berikut ini dalam mode rilis di luar debugger (konsol) mencetak:
Invoke: 19ms
DynamicInvoke: 3813ms
Kode:
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
. Mengapa Anda membandingkannya lebih dari 1 panggilan? Dan mengapa yang pertama membutuhkan waktu lebih lama dari panggilan fungsi kedua?