पठनीयता, अच्छा या बुरा सुधारने के लिए "अपवादों को पकड़ने" का उपयोग करना?


9

जब प्रोगैमैटिक प्रोग्रामर में अपवाद का उपयोग करने के लिए खंड में , पुस्तक लिखती है कि इसके बजाय:

retcode = OK;
     if (socket.read(name) != OK) {
      retcode = BAD_READ;
    }
     else {
      processName(name);
       if (socket.read(address) != OK) {
        retcode = BAD_READ;
      }
       else {
        processAddress(address);
         if (socket.read(telNo) != OK) {
          retcode = BAD_READ;
        }
         else {
          //  etc, etc...
        }
      }
    }
     return retcode;

, वे पसंद करते हैं:

 retcode = OK;
     try {
      socket.read(name);
      process(name);
      socket.read(address);
      processAddress(address);
      socket.read(telNo);
      //  etc, etc...
    }
     catch (IOException e) {
      retcode = BAD_READ;
      Logger.log( "Error reading individual: " + e.getMessage());
    }
     return retcode;

सिर्फ़ इसलिए कि यह भद्दी लगती है। मैं सभी के लिए neater कोड हूँ , हालांकि अपवादों को पकड़ने में अनावश्यक प्रदर्शन नहीं है?

मैं समझ सकता हूं कि हमें नटर कोड (कम से कम 99% बार) के लिए माइनसक्यूल ऑप्टिमाइज़ेशन छोड़ देना चाहिए, हालांकि जो मुझे पता है, उससे अपवादों को पकड़ना कोड के वर्ग से संबंधित है, जिन्हें रनटाइम में ध्यान देने योग्य देरी है। इसलिए मैं सोच रहा था कि कोड के दूसरे टुकड़े को पहले कोड पर पसंद करने का औचित्य क्या है?

या बल्कि, आप कौन सा कोड पसंद करेंगे?


कोड रिव्यू से माइग्रेट किया गया क्योंकि इसकी सबसे अच्छी प्रैक्टिस का सवाल है, कोड रिव्यू का सवाल नहीं
विंस्टन एवर्ट

1
IMO, अगर आप उम्मीद कर रहे हैं सॉकेट से उन valuse को पढ़ने के लिए सक्षम होने के लिए है, तो एक IOEx है असाधारण।
स्टीवन एवर्स


क्या आपने मापा है?

@ ThorbjørnRavnAndersen बेशक मैं किताब पढ़ रहा था और मापने के लिए एक वास्तविक "परीक्षण मामला" नहीं है .. लेकिन अगर हम इसे एक
दूषित

जवाबों:


18

अपवाद आमतौर पर केवल धीमे होते हैं यदि वे वास्तव में फेंक दिए जाते हैं। आमतौर पर, इस तरह की स्थितियों में अपवाद दुर्लभ हैं, इसलिए इसके बारे में आपको चिंता नहीं करनी चाहिए। आपको केवल अपवादों के प्रदर्शन के बारे में वास्तव में चिंता करनी चाहिए अगर वे हर समय हो रहे हैं और इस प्रकार एक महत्वपूर्ण कारक हैं।

दूसरा कोड बेहतर है क्योंकि तर्क का पालन करना बहुत आसान है। त्रुटि से निपटने का स्थानीय रूप से स्थानीयकरण है। आपत्ति केवल यह है कि यदि आप अपवादों का उपयोग कर रहे हैं, तो अपवादों का उपयोग करें। अपवादों को न पकड़ें और फिर एक त्रुटि कोड लौटाएं।


4
सहमत, मुझे ऐसी भाषा में त्रुटि कोड देखने से नफरत है जिसमें अपवाद हैं। ज्यादातर समय आपको कॉल स्टैक को तोड़ने के बिना , लॉग, रीथ्रो को पकड़ना चाहिए । और ज्यादातर समय, यह कोई फर्क नहीं पड़ता कि "अपवाद" मामला धीमा है। ऐप में एक समस्या है, इसे ठीक से संभालने के लिए समय निकालें। जब तक अपवाद असाधारण है, और सामान्य ऑपरेशन का हिस्सा नहीं है, या खुश मार्ग, आवेदन का, यह आमतौर पर एक कोड गंध नहीं है।
कैफ़ीक नेक

Btw मैं सोच रहा था कि हम EOFException को कैसे सही ठहराते हैं जो DataStreams लाइन के अंत का पता लगाने के लिए उपयोग करता है (लाइन का अंत असाधारण नहीं है) docs.oracle.com/javase/tutorial/essential/io/tatastreams.html में प्रदर्शित किया गया है ?
पचेरियर

@ स्पेसर, यह असाधारण हो सकता है। लाइन में इनपुट से बाहर चलना खराब डेटा या कुछ गलत होने का संकेत दे सकता है। मुझे संदेह है कि एक लाइन से कई फ़ील्ड को पार्स करने के लिए इरादा उपयोग है।
विंस्टन एवर्ट

@Downvoter, अगर आपको उत्तर में कोई समस्या है, तो कृपया समझाएं!
विंस्टन एवर्ट

5

खैर, जैसा कि वे भी कहते हैं, अपवादों को असाधारण मामलों को संभालना चाहिए , और चूंकि यह एक असाधारण मामला है (यानी ऐसा कुछ जो बीच में कुछ और दूर होता है) मैं कहूंगा कि यह यहां भी लागू होता है।

इसके अलावा, मैं इस तरह की सूक्ष्म-अनुकूलन चीजों के खिलाफ सलाह दूंगा। कोड की पठनीयता पर अधिक ध्यान दें , क्योंकि आप नया कोड लिखने की तुलना में अधिक समय पढ़ने वाले कोड पर खर्च करेंगे।

वास्तव में यह सुनिश्चित करने के लिए कि यह एक प्रदर्शन अड़चन है, कुछ प्रोफाइलिंग करें, और विश्लेषण करें और उस विश्लेषण के आधार पर अधिक महत्वपूर्ण कार्यों पर ध्यान केंद्रित करें।


5

मैं समझ सकता हूं कि हमें नटर कोड (कम से कम 99% बार) के लिए माइनसक्यूल ऑप्टिमाइज़ेशन छोड़ देना चाहिए, हालांकि जो मुझे पता है, उससे अपवादों को पकड़ना कोड के वर्ग से संबंधित है, जिन्हें रनटाइम में ध्यान देने योग्य देरी है।

तुम कहाँ से जानते हो? आप "ध्यान देने योग्य देरी" को कैसे परिभाषित करते हैं?

यह बिल्कुल अस्पष्ट (और पूरी तरह से गलत) प्रदर्शन मिथक है जो बेकार समयपूर्व अनुकूलन की ओर जाता है।

दो संख्याओं को जोड़ने की तुलना में एक अपवाद को फेंकना और पकड़ना धीमा हो सकता है, लेकिन सॉकेट से डेटा पढ़ने की तुलना में यह पूरी तरह से महत्वहीन है । आप शायद एक ही समय में एक हजार अपवादों को फेंक और पकड़ सकते हैं, जो आपने एकल नेटवर्क पैकेट पढ़ा है। और हम यहां हजारों अपवादों की बात नहीं कर रहे हैं, केवल एक ही है।


मैं .NET से आता हूं इसलिए जावा के अपने ज्ञान को क्षमा कर देता हूं, लेकिन मैंने व्यक्तिगत रूप से .NET में अपवादों को पकड़ने का अनुभव किया है, जिससे पागल देरी (सेकंड की भयावहता) होती है, जो "कैचिंग-अपवाद कोड" को हटाकर तय की गई थी ..
Pacerier

@Pacerier, गंभीरता से? सेकंड की परिमाण मुझे लगता है कि शायद यह बहुत सारे अपवादों को पकड़ रहा था? तब मैं देख सकता था।
विंस्टन इर्वर्ट

3
@ स्पेसर: यदि अपवाद पागल देरी का कारण बन रहे हैं, तो स्पष्ट रूप से क्या कारण है कि वे असाधारण नहीं हैं, और इसलिए उन्हें अन्य तरीकों से नियंत्रित किया जाना चाहिए। अपवाद को संसाधित करने के लिए किसी भी सिस्टम को सेकंड नहीं चाहिए, और मुझे लगता है कि इससे बचने के लिए Microsoft पर्याप्त रूप से सक्षम है।
डेविड थॉर्नले

5

मैं उन उत्तरों से सहमत होता हूँ जो आप पहले ही कह चुके हैं कि यह एक असाधारण मामला है, इसलिए यह उचित रूप से अपवाद हैंडलिंग का उपयोग करना है।

आपके प्रदर्शन की चिंताओं को अधिक सीधे संबोधित करते हुए, मुझे लगता है कि आपको चीजों के बारे में पैमाना रखने की जरूरत है। इन परिस्थितियों में एक अपवाद को फेंकना / पकड़ना एक माइक्रोसेकंड के एक आदेश को लेने की संभावना है। जैसा कि प्रवाह नियंत्रण जाता है, यह धीमा है - कई बार सामान्य ifबयानों की तुलना में धीमा होता है , इसके बारे में कोई सवाल नहीं है।

इसी समय, ध्यान रखें कि आप यहां क्या कर रहे हैं एक नेटवर्क से डेटा पढ़ रहा है। प्रति सेकंड 10 मेगाबिट्स (एक स्थानीय नेटवर्क के लिए धीमा, लेकिन इंटरनेट कनेक्शन के रूप में बहुत तेज), सूचना के एक बाइट को पढ़ने के समय के समान क्रम पर है ।

बेशक, यह ओवरहेड केवल तब होता है जब आप वास्तव में अपवाद को फेंक देते हैं - जब इसे फेंका नहीं जाता है, तो आमतौर पर बहुत कम या बिल्कुल ओवरहेड नहीं होता है (कम से कम मैंने जो देखा है, सबसे महत्वपूर्ण ओवरहेड नहीं है नियंत्रण के अधिक संभावित प्रवाह को जोड़ने से, कंपाइलर के रूप में अच्छी तरह से अनुकूलन करने के लिए कोड को कठिन बनाने से) अपवाद खुद को संभालना।

इस स्थिति में, जब कोई अपवाद फेंका जाता है, तो लॉग में आपका लेखन डेटा। लॉगिंग की प्रकृति को देखते हुए, संभावना बहुत अच्छी है कि जैसे ही आप इसे लिखते हैं (यह सुनिश्चित नहीं होता है कि यह खो नहीं गया है) आपका फ्लशिंग उस आउटपुट पर है। डिस्क पर लिखना (फिर से) काफी धीमा ऑपरेशन है - आपको एक बहुत तेज उद्यम-श्रेणी के एसएसडी की आवश्यकता है, यहां तक ​​कि दसियों हज़ारों IOP / सेकंड के दसियों की श्रेणी में आने के लिए। लॉगिंग के लिए उपयोग की जाने वाली डिस्क सैकड़ों IOP / सेकंड जैसी किसी चीज़ तक आसानी से सीमित हो सकती है।

निचला रेखा: ऐसे मामले हैं जहां ओवरहेड से निपटने के अपवाद महत्वपूर्ण हो सकते हैं, लेकिन यह लगभग निश्चित रूप से उनमें से एक नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.