यह सवाल कभी-कभार सामने आता है, लेकिन मैंने कोई संतोषजनक जवाब नहीं देखा है।
एक विशिष्ट पैटर्न है (पंक्ति एक DataRow है ):
if (row["value"] != DBNull.Value)
{
someObject.Member = row["value"];
}
मेरा पहला सवाल यह है कि कौन अधिक कुशल है (मैंने शर्त लगा दी है):
row["value"] == DBNull.Value; // Or
row["value"] is DBNull; // Or
row["value"].GetType() == typeof(DBNull) // Or... any suggestions?
यह इंगित करता है कि .GetType () तेज होना चाहिए, लेकिन शायद कंपाइलर कुछ चालें जानता है जो मैं नहीं करता हूं?
दूसरा सवाल, क्या यह पंक्ति ["मूल्य"] के मूल्य को रोकने के लायक है या क्या संकलक किसी भी तरह से अनुक्रमणिका का अनुकूलन करता है?
उदाहरण के लिए:
object valueHolder;
if (DBNull.Value == (valueHolder = row["value"])) {}
टिप्पणियाँ:
- पंक्ति ["मान"] मौजूद है।
- मुझे कॉलम का कॉलम इंडेक्स पता नहीं है (इसलिए कॉलम नाम लुकअप)।
- मैं विशेष रूप से DBNull और फिर असाइनमेंट (समय से पहले अनुकूलन के बारे में नहीं, आदि) की जाँच के बारे में पूछ रहा हूँ।
मैंने कुछ परिदृश्यों को चिह्नित किया (सेकंड में समय, 10,000,000 परीक्षण):
row["value"] == DBNull.Value: 00:00:01.5478995
row["value"] is DBNull: 00:00:01.6306578
row["value"].GetType() == typeof(DBNull): 00:00:02.0138757
Object.ReferenceEquals का प्रदर्शन "==" के समान है
सबसे दिलचस्प परिणाम? यदि आप मामले के आधार पर कॉलम का नाम मिसमैच करते हैं (उदाहरण के लिए, "वैल्यू" के बजाय "वैल्यू", तो यह लगभग दस गुना अधिक समय लेता है) (एक स्ट्रिंग के लिए):
row["Value"] == DBNull.Value: 00:00:12.2792374
कहानी की नैतिकता यह प्रतीत होती है कि यदि आप इसके सूचकांक द्वारा एक कॉलम नहीं देख सकते हैं, तो यह सुनिश्चित करें कि आप जिस कॉलम का नाम इंडेक्सर को खिलाते हैं, वह DataColumn के नाम से बिल्कुल मेल खाता है।
मूल्य कैशिंग भी तेजी से लगभग दो बार प्रतीत होता है :
No Caching: 00:00:03.0996622
With Caching: 00:00:01.5659920
तो सबसे कुशल तरीका लगता है:
object temp;
string variable;
if (DBNull.Value != (temp = row["value"]))
{
variable = temp.ToString();
}
IDataRecord
एक्सटेंशन पसंद करेंगे ।