2010-04-13 8 views
37

मुझे बताया गया है कि जावा कोशिश-पकड़ तंत्र का उपयोग करने में कुछ ओवरहेड है। इसलिए, संभावित अपवाद को संभालने के लिए प्रयास ब्लॉक के भीतर चेक अपवाद को फेंकने के तरीकों को रखना जरूरी है, लेकिन प्रयासों को केवल उन परिचालनों को शामिल करने के लिए प्रयास करें जो कि अपवाद फेंक सकते हैं।जावा को जितना संभव हो उतना कसकर ब्लॉक करने की कोशिश करनी चाहिए?

मुझे यकीन नहीं है कि यह एक समझदार निष्कर्ष है।

किसी फ़ंक्शन के नीचे दो कार्यान्वयन पर विचार करें जो निर्दिष्ट टेक्स्ट फ़ाइल को संसाधित करता है।

भले ही यह सच है कि पहला व्यक्ति कुछ अनावश्यक ओवरहेड लेता है, मुझे इसका पालन करना बहुत आसान लगता है। यह स्पष्ट नहीं है कि बिल्कुल अपवाद केवल बयानों को देखने से ही आते हैं, लेकिन टिप्पणियां स्पष्ट रूप से दिखाती हैं कि कौन से बयान जिम्मेदार हैं।

दूसरा दूसरा पहले से कहीं अधिक जटिल और जटिल है। विशेष रूप से, पहले की अच्छी लाइन-रीडिंग मुहावरे को readLine को एक कोशिश ब्लॉक में कॉल करने के लिए उलझाया जाना चाहिए।

एक funcion में अपवादों को संभालने के लिए सबसे अच्छा अभ्यास क्या है जहां इसकी परिभाषा में कई अपवाद फेंक दिए जा सकते हैं?

यह एक शामिल कोशिश ब्लॉक के भीतर सभी प्रसंस्करण कोड:

void processFile(File f) 
{ 
    try 
    { 
    // construction of FileReader can throw FileNotFoundException 
    BufferedReader in = new BufferedReader(new FileReader(f)); 

    // call of readLine can throw IOException 
    String line; 
    while ((line = in.readLine()) != null) 
    { 
     process(line); 
    } 
    } 
    catch (FileNotFoundException ex) 
    { 
    handle(ex); 
    } 
    catch (IOException ex) 
    { 
    handle(ex); 
    } 
} 

यह एक ही तरीके कि कोशिश ब्लॉक के भीतर अपवाद फेंक शामिल हैं:

void processFile(File f) 
{ 
    FileReader reader; 
    try 
    { 
    reader = new FileReader(f); 
    } 
    catch (FileNotFoundException ex) 
    { 
    handle(ex); 
    return; 
    } 

    BufferedReader in = new BufferedReader(reader); 

    String line; 
    while (true) 
    { 
    try 
    { 
     line = in.readLine(); 
    } 
    catch (IOException ex) 
    { 
     handle(ex); 
     break; 
    } 

    if (line == null) 
    { 
     break; 
    } 

    process(line); 
    } 
} 
+10

"समयपूर्व अनुकूलन" एक ऐसी स्थिति का वर्णन करने के लिए प्रयोग किया जाता है जहां एक प्रोग्रामर प्रदर्शन विचारों को कोड के टुकड़े के डिजाइन को प्रभावित करता है। इसका परिणाम ऐसे डिज़ाइन में हो सकता है जो उतना स्वच्छ नहीं हो सकता है जितना कि यह गलत हो या कोड गलत हो, क्योंकि कोड अनुकूलन द्वारा जटिल है और प्रोग्रामर अनुकूलन से विचलित है। - विकिपीडिया [http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize] –

+2

"हमें छोटी क्षमता के बारे में भूल जाना चाहिए, समय के बारे में 9 7% कहें: समयपूर्व अनुकूलन सभी बुराइयों की जड़ है। फिर भी हमें पास नहीं करना चाहिए उस महत्वपूर्ण 3% में हमारे अवसरों को ऊपर उठाएं। " - Knuth [http://stackoverflow.com/questions/211414/is-premature-optimization-really-the-root-of-all-evil] –

उत्तर

45

मूल आधार यहां झूठा है:try ब्लॉक का आकार प्रदर्शन में कोई फर्क नहीं पड़ता। वास्तव में रनटाइम पर अपवाद उठाकर प्रदर्शन प्रभावित होता है, और यह try ब्लॉक के आकार से स्वतंत्र है।

हालांकि, छोटे ब्लॉक को रोकने के लिए बेहतर कार्यक्रम हो सकते हैं।

आप पुनर्प्राप्ति और आगे बढ़ने के लिए अपवाद पकड़ सकते हैं, या आप उन्हें कॉलर (या कुछ यूआई के माध्यम से) को रिपोर्ट करने के लिए बस उन्हें पकड़ सकते हैं।

पहले मामले में, जिन विफलताओं से आप पुनर्प्राप्त कर सकते हैं वे अक्सर बहुत विशिष्ट होते हैं, और इससे try ब्लॉक छोटे होते हैं।

दूसरे मामले में, जहां एक अपवाद पकड़ा जाता है ताकि इसे किसी अन्य अपवाद द्वारा लपेटा जा सके और फिर से फेंक दिया जा सके, या उपयोगकर्ता को प्रदर्शित किया जा सके, छोटे try ब्लॉक का मतलब है कि आप जानते हैं कि कौन सा ऑपरेशन विफल रहा है, और उच्च -वेल संदर्भ जिसमें कॉल किया गया था। यह आपको अधिक विशिष्ट त्रुटि रिपोर्ट बनाने की अनुमति देता है।

बेशक, वहां & hellip हैं; इन दिशानिर्देशों के लिए अपवाद (क्षमा करें!)। उदाहरण के लिए, कुछ मामलों में बहुत विशिष्ट त्रुटि रिपोर्ट सुरक्षा समस्या हो सकती है।


यह क्या प्रभाव एक try ब्लॉक संकलित कोड पर है पता करने के लिए उपयोगी हो सकता है। यह संकलित निर्देशों को बिल्कुल भी नहीं बदलता है! (बेशक, संबंधित catch ब्लॉक करता है, क्योंकि यह किसी अन्य कोड की तरह है।)

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

यह समझने की महत्वपूर्ण बात यह है कि जब तक इसकी आवश्यकता न हो, इस तालिका से परामर्श नहीं किया जाता है (और प्रदर्शन चलाने पर इसका कोई प्रभाव नहीं पड़ता)। (कक्षा के लोडिंग में थोड़ा ओवरहेड चुनना।)

+6

बिल्कुल। रिकार्ड के लिए यह ध्यान देने योग्य भी है कि ट्राइक-कैच से जुड़ा ओवरहेड तब होता है जब एक अपवाद फेंक दिया जाता है या ब्लॉक में आखिरकार खंड होता है, जैसा वीएम स्पेक में विस्तृत है http://java.sun.com/docs/ किताबें/JVMs/second_edition/html/Compiling.doc.html # 9934। – ig0774

+0

@ ig0774 तो, अगर मैं अंततः ब्लॉक 'अंत {in.close() की तरह जोड़ता हूं; } ', तो संबंधित ओवरहेड प्रभावी होता है? मैं कल्पना के बारे में क्या समझता हूं, अंत में खंड सामान्य रूप से लौटने से पहले अंततः ब्लॉक को सबराउटिन के रूप में कॉल करने के लिए संकलित प्रयास ब्लॉक में एक अतिरिक्त निर्देश जोड़ता है। Spec के संदर्भ के लिए –

+0

+1, बीटीडब्ल्यू। –

1

वहाँ करने के लिए बहुत बहुत कम फायदा है दूसरी विधि। आखिरकार यदि आप फ़ाइल को सफलतापूर्वक खोल सकते हैं लेकिन इससे नहीं पढ़ते हैं, तो आपके कंप्यूटर के साथ कुछ गड़बड़ है। इस प्रकार यह जानकर कि IO अपवाद readLine() विधि से आया है बहुत ही कम उपयोगी है। जैसा कि आप जानते हैं, अलग-अलग समस्याओं के लिए अलग-अलग अपवाद फेंक दिए जाते हैं (फ़ाइल नॉटफाउंड एक्सेप्शन, इत्यादि)

जब तक आप इसे 'तार्किक' ब्लॉक के साथ गुंजाइश करते हैं, यानी 1 फ़ाइल में फ़ाइल खोलना, पढ़ना और बंद करना, मैं चाहता हूं पहली विधि के साथ जाओ। पढ़ने के लिए यह बहुत आसान है और, विशेष रूप से जब आईओ से निपटने के दौरान, कोशिश-पकड़ ओवरहेड द्वारा उपयोग किए जाने वाले प्रोसेसर चक्र कम से कम होंगे।

0

दूसरी विधि एक कंपाइलर त्रुटि उत्पन्न करेगी जो reader प्रारंभ नहीं हो सकती है। आप इसे null पर प्रारंभ करके प्राप्त कर सकते हैं, लेकिन इसका मतलब है कि आप एक एनपीई प्राप्त कर सकते हैं, और इसका कोई फायदा नहीं है।

+0

ऐसी कोई संकलक त्रुटि उत्पन्न नहीं की जाएगी। 'पकड़' ब्लॉक के अंत में 'वापसी' कथन सुनिश्चित करता है कि पाठक प्रारंभ किया जाएगा या कभी नहीं पढ़ा जाएगा! बेशक, मैंने केवल इस कथन को जोड़ा है कि संकलक ने वास्तव में आपके द्वारा वर्णित त्रुटि जारी की है। :) –

+0

काफी - मुझे याद आया। ईमानदारी का शुक्र है कि संकलक हमारे लिए इस सामान को समझने के लिए यहां है। :) –

11

मुझे बताया गया है कि जावा कोशिश-पकड़ तंत्र का उपयोग करने में कुछ ओवरहेड है।

बिल्कुल। और विधि कॉल के लिए ओवरहेड भी है। लेकिन आपको अपना पूरा कोड एक विधि में नहीं रखना चाहिए।

समयपूर्व अनुकूलन सींग को टॉट नहीं करना है, लेकिन फोकस पढ़ने, संगठन इत्यादि की आसानी से होना चाहिए। भाषा संरचनाओं में शायद ही कभी सिस्टम संगठन और एल्गोरिदम की पसंद के रूप में प्रदर्शन पर असर पड़ता है।

मेरे लिए, सबसे पहले पढ़ने के लिए सबसे आसान है।

1

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

हालांकि, अधिकांश लोगों द्वारा संदर्भित प्रदर्शन समस्या अपवाद को बढ़ाने के लिए संबंधित है, न कि स्वयं को ब्लॉक करने का प्रयास करें।

दूसरे शब्दों में, जब तक आप कभी भी कोई त्रुटि नहीं उठाते हैं, तो प्रयास ब्लॉक प्रदर्शन को प्रभावित नहीं करेगा। आपको किसी अन्य प्रवाह नियंत्रण निर्माण को ब्लॉक करने का प्रयास नहीं करना चाहिए और अपने कोड के माध्यम से शाखा में त्रुटि उत्पन्न करना चाहिए। यही वह है जिसे आप टालना चाहते हैं।

+2

आपके पिछले अनुच्छेद पर बस एक अतिरिक्त नोट। यदि आपके पास लूप के अंदर * पकड़/पकड़ * है, तो आप अपवाद पकड़ सकते हैं और लूपिंग जारी रख सकते हैं। यदि आपका प्रयास/पकड़ लूप के * बाहर * है, तो आपका लूपिंग निरस्त कर दिया जाएगा। कोई भी आप जो चाहते हैं वह हो सकता है और जहां आप कोशिश/पकड़ डालते हैं उस पर प्रभाव डालेगा। –

3

नहीं। केवल एक चीज जिस पर आपको विचार करना चाहिए, वह है जहां आप अपवाद को उचित रूप से संभालने और संसाधनों को पुनः प्राप्त करने के लिए आवश्यक संसाधनों को संभालने के लिए कहां कर सकते हैं।

+0

+1। ओपी में केवल पहला कार्यान्वयन खुद को एक 'अंत' खंड जोड़ने के लिए उधार देता है जो फ़ाइल को बंद करता है। क्लीनअप का उल्लेख करने के लिए –

+0

+1। अब तक मैंने कभी भी 'रीडर' ऑब्जेक्ट्स पर इस्तेमाल नहीं किया था जिसे मैंने इस्तेमाल किया था। मुझ पर शर्म की बात है! –

+0

जावा 7 कोशिश-संसाधनों के साथ आपकी वरीयताओं को कितना बदलता है? –

2

यह सबसे खराब समय पर अनुकूलन अनुकूलन है। ऐसा मत करो

"हमें छोटी क्षमता के बारे में भूल जाना चाहिए, समय के बारे में 9 7% कहें: समयपूर्व अनुकूलन सभी बुराइयों की जड़ है" - Knuth।

संबंधित मुद्दे

 संबंधित मुद्दे