EDIT 11/20/2009 :
मैं प्रबंधित कोड प्रदर्शन को बेहतर बनाने के लिए MSDN के इस लेख को पढ़ रहा था और इस हिस्से ने मुझे इस प्रश्न की याद दिला दी:
अपवाद फेंकने की प्रदर्शन लागत महत्वपूर्ण है। यद्यपि संरचित अपवाद हैंडलिंग त्रुटि स्थितियों से निपटने का अनुशंसित तरीका है, सुनिश्चित करें कि आप अपवाद का उपयोग केवल असाधारण परिस्थितियों में करते हैं जब त्रुटि की स्थिति उत्पन्न होती है। नियमित नियंत्रण प्रवाह के लिए अपवादों का उपयोग न करें।
बेशक, यह केवल .NET के लिए है, और यह विशेष रूप से उन उच्च-प्रदर्शन अनुप्रयोगों को विकसित करने के लिए भी निर्देशित है (जैसे स्वयं); इसलिए यह स्पष्ट रूप से एक सार्वभौमिक सत्य नहीं है। फिर भी, वहाँ हम में से बहुत सारे .NET डेवलपर्स हैं, इसलिए मुझे लगा कि यह ध्यान देने योग्य है।
संपादित करें :
ठीक है, सबसे पहले, चलो एक बात सीधे करें: प्रदर्शन के सवाल पर मेरा किसी से झगड़ा करने का कोई इरादा नहीं है। सामान्य तौर पर, वास्तव में, मैं उन लोगों से सहमत होने के लिए इच्छुक हूं जो मानते हैं कि समय से पहले अनुकूलन एक पाप है। हालाँकि, मुझे सिर्फ दो बिंदु बनाने हैं:
पोस्टर पारंपरिक ज्ञान के पीछे एक उद्देश्यपूर्ण तर्क के लिए कह रहा है कि अपवादों को संयम से इस्तेमाल किया जाना चाहिए। हम पठनीयता और उचित डिज़ाइन पर चर्चा कर सकते हैं जो हम चाहते हैं; लेकिन ये दोनों तरफ से बहस करने के लिए तैयार लोगों के साथ व्यक्तिपरक मामले हैं। मुझे लगता है कि पोस्टर से इस बारे में पता चलता है। तथ्य यह है कि कार्यक्रम प्रवाह को नियंत्रित करने के लिए अपवादों का उपयोग करना अक्सर चीजों को करने का एक अक्षम तरीका है। नहीं, हमेशा नहीं , लेकिन अक्सर । यही कारण है कि यह उचित सलाह है कि अपवादों का संयम से उपयोग करें, ठीक उसी तरह जैसे कि लाल मांस खाने या शराब पीने से बचना अच्छी सलाह है।
बिना किसी अच्छे कारण के अनुकूलन करने और कुशल कोड लिखने के बीच अंतर है। इस के लिए कोरलरी यह है कि कुछ लिखने के बीच अंतर है जो मजबूत है, अगर अनुकूलित नहीं है, और कुछ ऐसा है जो सिर्फ सादा अक्षम है। कभी-कभी मुझे लगता है कि जब लोग अपवाद की तरह की चीजों पर बहस करते हैं, तो वे वास्तव में सिर्फ एक-दूसरे से बात कर रहे होते हैं, क्योंकि वे मौलिक रूप से अलग-अलग चीजों पर चर्चा कर रहे होते हैं।
मेरी बात को समझाने के लिए, निम्नलिखित C # कोड उदाहरणों पर विचार करें।
उदाहरण 1: अमान्य उपयोगकर्ता इनपुट का पता लगाना
यह एक उदाहरण है कि मैं अपवाद दुरुपयोग क्या कहूंगा ।
int value = -1;
string input = GetInput();
bool inputChecksOut = false;
while (!inputChecksOut) {
try {
value = int.Parse(input);
inputChecksOut = true;
} catch (FormatException) {
input = GetInput();
}
}
यह कोड मेरे लिए हास्यास्पद है। बेशक यह काम करता है । उसके साथ किसी की बहस नहीं हुई। लेकिन यह कुछ इस तरह होना चाहिए :
int value = -1;
string input = GetInput();
while (!int.TryParse(input, out value)) {
input = GetInput();
}
उदाहरण 2: फ़ाइल के अस्तित्व की जाँच करना
मुझे लगता है कि यह परिदृश्य वास्तव में बहुत सामान्य है। यह निश्चित रूप से बहुत अधिक लोगों को "स्वीकार्य" लगता है, क्योंकि यह फ़ाइल I / O से संबंधित है:
string text = null;
string path = GetInput();
bool inputChecksOut = false;
while (!inputChecksOut) {
try {
using (FileStream fs = new FileStream(path, FileMode.Open)) {
using (StreamReader sr = new StreamReader(fs)) {
text = sr.ReadToEnd();
}
}
inputChecksOut = true;
} catch (FileNotFoundException) {
path = GetInput();
}
}
यह उचित पर्याप्त लगता है, है ना? हम एक फ़ाइल खोलने की कोशिश कर रहे हैं; अगर यह नहीं है, तो हम उस अपवाद को पकड़ लेते हैं और एक अलग फाइल खोलने की कोशिश करते हैं ... इसमें गलत क्या है?
कुछ भी सच नहीं। लेकिन इस विकल्प पर विचार करें, जिसमें कोई अपवाद नहीं है:
string text = null;
string path = GetInput();
while (!File.Exists(path)) path = GetInput();
using (FileStream fs = new FileStream(path, FileMode.Open)) {
using (StreamReader sr = new StreamReader(fs)) {
text = sr.ReadToEnd();
}
}
बेशक, अगर इन दो दृष्टिकोणों का प्रदर्शन वास्तव में एक ही था, तो यह वास्तव में एक सैद्धांतिक मुद्दा होगा। तो, चलिए एक नज़र डालते हैं। पहले कोड के उदाहरण के लिए, मैंने 10000 यादृच्छिक स्ट्रिंग्स की एक सूची बनाई, जिनमें से कोई भी एक उचित पूर्णांक का प्रतिनिधित्व नहीं करता था, और फिर बहुत अंत में एक वैध पूर्णांक स्ट्रिंग जोड़ा। उपरोक्त दोनों दृष्टिकोणों का उपयोग करना, ये मेरे परिणाम थे:
का उपयोग कर try
/ catch
ब्लॉक : 25.455 सेकंड
का उपयोग कर int.TryParse
: 1.637 मिलीसेकंड
दूसरे उदाहरण के लिए, मैंने मूल रूप से एक ही काम किया: 10000 यादृच्छिक तारों की एक सूची बनाई, जिनमें से कोई भी एक वैध पथ नहीं था, फिर बहुत ही अंत में एक वैध मार्ग जोड़ा। ये परिणाम थे:
का उपयोग कर try
/ catch
ब्लॉक: 29.989 सेकंड
का उपयोग करना File.Exists
: 22.820 मिलीसेकंड
बहुत से लोग इस पर प्रतिक्रिया देते हुए कहते हैं, "हाँ, ठीक है, 10,000 अपवादों को फेंकना और पकड़ना बेहद अवास्तविक है; इससे परिणाम अतिरंजित होते हैं।" बिलकुल यह करता है। एक अपवाद को फेंकने और अपने आप पर खराब इनपुट को संभालने के बीच का अंतर उपयोगकर्ता के लिए ध्यान देने योग्य नहीं है। तथ्य यह है कि अपवादों का उपयोग करते हुए, इन दो मामलों में, 1,000 से 10,000 गुना अधिक वैकल्पिक दृष्टिकोणों की तुलना में धीमा है जो कि केवल पठनीय हैं - यदि ऐसा नहीं है।
इसलिए मैंने GetNine()
नीचे दी गई विधि का उदाहरण शामिल किया । ऐसा नहीं है कि यह असहिष्णु रूप से धीमा है या अस्वीकार्य रूप से धीमा है; यह है कि यह धीमी गति से होना चाहिए ... बिना किसी अच्छे कारण के ।
फिर, ये सिर्फ दो उदाहरण हैं। बेशक , ऐसे समय होंगे जब अपवादों का उपयोग करने का प्रदर्शन हिट नहीं होता है (पैवेल का अधिकार; आखिरकार, यह कार्यान्वयन पर निर्भर करता है)। मैं केवल इतना कह रहा हूं: चलो तथ्यों का सामना करते हैं, दोस्तों - ऊपर दिए गए मामलों में, अपवाद को फेंकना और पकड़ना इसके अनुरूप है GetNine()
; यह कुछ करने का एक अक्षम तरीका है जिसे आसानी से बेहतर किया जा सकता है ।
आप एक तर्क के लिए पूछ रहे हैं जैसे कि यह उन स्थितियों में से एक है जहां हर कोई बिना किसी कारण के एक बैंडवाले पर कूद गया। लेकिन वास्तव में उत्तर स्पष्ट है, और मुझे लगता है कि आप इसे पहले से ही जानते हैं। अपवाद हैंडलिंग में भयावह प्रदर्शन है।
ठीक है, शायद यह आपके विशेष रूप से व्यावसायिक परिदृश्य के लिए ठीक है, लेकिन अपेक्षाकृत बोलना , फेंकना / पकड़ना एक तरह से अधिक ओवरहेड का परिचय देता है, कई मामलों में आवश्यक है। आप इसे जानते हैं, मैं इसे जानता हूं: अधिकांश समय , यदि आप प्रोग्राम प्रवाह को नियंत्रित करने के लिए अपवादों का उपयोग कर रहे हैं, तो आप केवल धीमी कोड लिख रहे हैं।
आप यह भी पूछ सकते हैं: यह कोड खराब क्यों है?
private int GetNine() {
for (int i = 0; i < 10; i++) {
if (i == 9) return i;
}
}
मैं शर्त लगाता हूं कि यदि आप इस फ़ंक्शन को पूरा करते हैं, तो आप पाएंगे कि यह आपके विशिष्ट व्यावसायिक अनुप्रयोग के लिए काफी तेजी से प्रदर्शन करता है। यह इस तथ्य को नहीं बदलता है कि यह किसी चीज़ को पूरा करने का एक बहुत ही अयोग्य तरीका है जिसे बहुत बेहतर किया जा सकता है।
जब लोग अपवाद के बारे में बात करते हैं तो इसका मतलब है "दुरुपयोग।"