मैं एक बहुत ही हास्यास्पद परिस्थिति में आया जहां एक सामान्य विधि के अंदर एक शून्य प्रकार को शून्य से तुलना करना एक मान प्रकार या संदर्भ प्रकार की तुलना में 234x धीमा है।एक सामान्य विधि पर शून्य करने के लिए एक शून्य विधि की तुलना करने के लिए धीमा क्यों है, जिसमें कोई बाधा नहीं है?
static bool IsNull<T>(T instance)
{
return instance == null;
}
निष्पादन कोड है:: कोड इस प्रकार है
int? a = 0;
string b = "A";
int c = 0;
var watch = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
var r1 = IsNull(a);
}
Console.WriteLine(watch.Elapsed.ToString());
watch.Restart();
for (int i = 0; i < 1000000; i++)
{
var r2 = IsNull(b);
}
Console.WriteLine(watch.Elapsed.ToString());
watch.Restart();
for (int i = 0; i < 1000000; i++)
{
var r3 = IsNull(c);
}
watch.Stop();
Console.WriteLine(watch.Elapsed.ToString());
Console.ReadKey();
ऊपर कोड के लिए उत्पादन होता है:
00: 00: 00,1879827
00:00: 00.0008779
00: 00: 00.0008532
जैसा कि आप देख सकते हैं, एक शून्य या एक स्ट्रिंग की तुलना में शून्य के लिए एक शून्य से int की तुलना धीमी है 234x धीमी है। अगर मैं सही बाधाओं के साथ एक दूसरे अधिभार जोड़ने के लिए, परिणाम नाटकीय रूप से बदल:
static bool IsNull<T>(T? instance) where T : struct
{
return instance == null;
}
अब परिणाम हैं:
00: 00: ००.०००६०४०
00: 00: 00,0006017
00: 00: 00.0006014
वह क्यों है? मैंने बाइट कोड की जांच नहीं की क्योंकि मैं इस पर धाराप्रवाह नहीं हूं, लेकिन बाइट कोड थोड़ा अलग था, लेकिन मैं उम्मीद करता हूं कि जेआईटी इसे अनुकूलित करेगी, और यह नहीं है (मैं अनुकूलन के साथ चल रहा हूं) ।
ऐसे परिणामों के साथ - सबसे खराब मामले में 1 एम पुनरावृत्तियों के लिए 0.2 सेकंड के तहत, क्या इससे कोई फर्क पड़ता है? – Oded
हां यह करता है यदि आप यह 1 एम एक सेकंड करते हैं। मैं करता हूँ। –
यह न भूलें कि आप लाखों पुनरावृत्तियों की लागत का योग माप रहे हैं * और पहले कॉल * पर कोड को जंप करने की लागत। यदि कोड वास्तव में सस्ता है, क्योंकि यह कोड है, तो जिट लागत जो केवल एक बार होती है वह वास्तव में औसत पर हावी हो सकती है। परीक्षण को दो बार एक ही प्रोग्राम में चलाने में दिलचस्प हो सकता है ताकि दूसरी बार कोड "गर्म" हो। –