जवाबों:
जब आपके पास एक प्रतिनिधि उदाहरण होता है, तो आपको सटीक प्रकार पता हो सकता है, या आप बस यह जान सकते हैं कि यह एक है 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[]
।
प्रदर्शन की तुलना के लिए, डिबगर के बाहर रिलीज़ मोड में (कंसोल कंसोल) प्रिंट करता है:
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
। आप उनकी तुलना 1 कॉल से अधिक क्यों कर रहे हैं? और पहले वाले को फ़ंक्शन की दूसरी कॉल से अधिक समय क्यों लगता है?