2010-07-10 8 views
28

जांचने में त्रुटि क्या विभिन्न त्रुटि जांच करने के बजाए केवल कोशिश-पकड़ ब्लॉक के अंदर कोड डालना तेज होगा?जावास्क्रिप्ट कोशिश-पकड़ प्रदर्शन बनाम। कोड

उदाहरण के लिए ..

function getProjectTask(projectTaskId) { 
    if (YAHOO.lang.isUndefined(projectTaskId) || YAHOO.lang.isNull(projectTaskId) && !YAHOO.lang.isNumber(projectTaskId)) { 
     return null; 
    } 

    var projectPhaseId, projectPhaseIndex, projectTaskIndex, projectPhases, projectPhase, projectTask; 

    if (!YAHOO.lang.hasOwnProperty(projectTaskPhaseMap, projectTaskId)) { 
     return null; 
    } 

    projectPhaseId = projectTaskPhaseMap[projectTaskId]; 

    if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhasesMap, projectPhaseId)) { 
     return null; 
    } 

    projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId]; 
    if (YAHOO.lang.isUndefined(projectPhaseIndex) || YAHOO.lang.isNull(projectPhaseIndex) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhases[projectPhaseIndex])) { 
     return null; 
    } 
    projectPhase = scheduleData.ProjectPhases[projectPhaseIndex]; 

    if (!YAHOO.lang.hasOwnProperty(projectPhase.ProjectTasksMap, projectTaskId)) { 
     return null; 
    } 

    projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId]; 

    if (YAHOO.lang.isUndefined(projectTaskIndex) || YAHOO.lang.isNull(projectTaskIndex)) { 
     return null; 
    } 

    projectTask = scheduleData.ProjectTasks[projectTaskIndex]; 
} 

वी.एस.

function getProjectTask(projectTaskId) { 
    try { 
     projectPhaseId = projectTaskPhaseMap[projectTaskId]; 
     projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId]; 
     projectPhase = scheduleData.ProjectPhases[projectPhaseIndex]; 
     projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId]; 
     projectTask = scheduleData.ProjectTasks[projectTaskIndex]; 

    } 
    catch (e) { 
     return null; 
    } 
} 

मुझे आशा है कि मेरे सवाल समझ में आता है। मुझे स्पष्ट करने में खुशी होगी। धन्यवाद!

+0

यहां तक ​​कि 'फ़ंक्शन isNull (c) 'बेकार है, मेरा जवाब देखें ... :) – galambalazs

+3

मैं यूयूआई से परिचित नहीं हूं, मुझे बस कोड से नफरत है जो मुझे किनारे पर स्क्रॉल करता है! –

+0

मैं या तो यूयूआई से परिचित नहीं हूं, लेकिन शून्य की जांच कर रहा हूं || अनिर्धारित जावास्क्रिप्ट – galambalazs

उत्तर

46

"प्रोग्राम लोगों पढ़ने के लिए लिखा होना चाहिए, और केवल संयोग से मशीनों पर अमल करने के लिए।"

Abelson & Sussman, SICP, प्रथम संस्करण

हमेशा पठनीय कोड के लिए लक्ष्य के लिए प्रस्तावना। याद करने के लिए महत्वपूर्ण बात यह है: प्रदर्शन-महत्वपूर्ण कार्यों में

बचें कोशिश पकड़ है, और

कहीं भी किसी और

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

लेकिन जैसा कि मैंने देखा है कि आप त्रुटि जांच के लिए कुछ फ़ंक्शंस का स्पष्ट रूप से दुरुपयोग करते हैं। जटिल जांच के बजाय आप वांछित वस्तुओं और वस्तुओं के गुणों का परीक्षण करने से पहले परीक्षण कर सकते हैं। और:

if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId)) 

if (projectPhaseId != null) 

उदाहरण के लिए के रूप में लिखा जा सकता है ... तो उपरोक्त उदाहरण भी कैच कोशिश के बिना काफी पठनीय हो सकता है। आप यूयूआई का दुरुपयोग करते हैं।

मैं शर्त है कि इस काम करता है अपेक्षा के अनुरूप:

function getProjectTask(projectTaskId) { 

    var projectPhaseId = projectTaskPhaseMap[projectTaskId], 
     projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId], 
     projectPhase  = scheduleData.ProjectPhases[projectPhaseIndex]; 

    if (projectPhase == null) return null; // projectPhase would break the chain 

    var projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId], 
     projectTask  = scheduleData.ProjectTasks[projectTaskIndex]; 

    return projectTask || null; // end of the dependency chain 

} 

शांत कि कैसी है? :)

+9

अच्छी तरह से डाल दिया।मैं बस यह जोड़ना चाहता हूं कि जब तक आपके पास वास्तव में कोई प्रदर्शन समस्या न हो, तो आपके कोड को पठनीय बनाने के लिए सबसे अच्छा है। जब आपके पास वास्तव में प्रदर्शन समस्या होती है, तो पहले समस्या कहां मापें, केवल तभी अनुकूलित करें। अन्यथा आप गलत चीजों को अनुकूलित करने में काफी समय व्यतीत कर सकते हैं। –

+11

+1 के लिए +1 "लोगों को पढ़ने के लिए कार्यक्रमों को लिखा जाना चाहिए, और मशीनों को निष्पादित करने के लिए केवल आकस्मिक रूप से।" –

+0

यह एक उत्कृष्ट उत्तर है। अपवाद हैंडलिंग कोड के खिलाफ ओपन सोर्स समुदाय की सतत लड़ाई रोने के बावजूद, कोशिश-पकड़ का उपयोग करने के लिए कई बार और मामले हैं। इससे कोई फ़र्क नहीं पड़ता कि आपका कोड कितना तेज़ है, अगर कोई भी इसे छोड़कर समझ, समझ या बनाए रखता है। – whoblitz

3

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

0

ध्यान रखें कि यह ब्राउज़र पर भी भिन्न होता है लेकिन समग्र रूप से मैंने कोशिश/पकड़ ब्लॉक का उपयोग करने के लिए महत्वपूर्ण प्रदर्शन दंड के बारे में कुछ भी नहीं पढ़ा है। लेकिन इनका उपयोग करने में वास्तव में एक अच्छा अभ्यास नहीं है क्योंकि आप यह बताने में सक्षम नहीं हैं कि समस्या क्यों विफल रही।

यहां कुछ जावास्क्रिप्ट प्रदर्शन विचारों का एक दिलचस्प स्लाइड शो है। स्लाइड 76 पर वे कोशिश/पकड़ ब्लॉक और प्रदर्शन प्रभाव को कवर करते हैं। http://www.slideshare.net/madrobby/extreme-javascript-performance

1

स्थिति पर निर्भर करता है। चूंकि गैलांबलाज का उल्लेख पठनीयता महत्वपूर्ण है। पर विचार करें:

function getCustomer (id) { 
    if (typeof data!='undefined' && data.stores && data.stores.customers 
     && typeof data.stores.customers.getById=='function') { 
    return data.stores.customers.getById(id); 
    } else { 
    return null; 
    } 
} 

तुलना करने के लिए:

function getCustomer (id) { 
    try {return data.stores.customers.getById(id);} catch (e) { return null; } 
} 

मैं कहना चाहता हूँ दूसरा और अधिक पठनीय है। आप Google की एपिस या ट्विटर की फीड जैसी चीजों से डेटा वापस प्राप्त करते हैं (आमतौर पर गहराई से घोंसले वाले तरीकों के साथ नहीं, यह सिर्फ प्रदर्शन के लिए है)।

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

28

तर्क के लिए तथ्य आधार क्यों नहीं है?

var Speedy = function() { 
    this.init(); 
}; 
Speedy.prototype = { 
    init: function() { 
     var i, t1; 
     this.sumWith = 0; 
     this.sumWithout = 0; 
     this.countWith = 0; 
     this.countWithout = 0; 
     for (i = 0; i < 5; i++) { 
      t1 = this.getTime(); 
      console.log("Using Try/Catch, Trial #" + (i + 1)); 
         console.log("started " + t1); 
      this.goTry(t1); 
      this.countWith++; 
     } 
     for (i = 0; i < 5; i++) { 
      t1 = this.getTime(); 
      console.log("W/out Try/Catch, Trial #" + (i + 1)); 
      console.log("started :" + t1); 
      this.goAlone(t1); 
      this.countWithout++; 
     } 
     for (i = 5; i < 10; i++) { 
      t1 = this.getTime(); 
      console.log("Using Try/Catch, Trial #" + (i + 1)); 
      console.log("started :" + t1); 
      this.goTry(t1); 
      this.countWith++; 
     } 
     for (i = 5; i < 10; i++) { 
      t1 = this.getTime(); 
      console.log("W/out Try/Catch, Trial #" + (i + 1)); 
      console.log("started :" + t1); 
      this.goAlone(t1); 
      this.countWithout++; 
     } 
     console.log("---------------------------------------"); 
     console.log("Average time (ms) USING Try/Catch: " + this.sumWith/this.countWith + " ms"); 
     console.log("Average time (ms) W/OUT Try/Catch: " + this.sumWithout/this.countWithout + " ms"); 
     console.log("---------------------------------------"); 
    }, 

    getTime: function() { 
     return new Date(); 
    }, 

    done: function(t1, wasTry) { 
     var t2 = this.getTime(); 
     var td = t2 - t1; 
     console.log("ended.....: " + t2); 
     console.log("diff......: " + td); 
     if (wasTry) { 
      this.sumWith += td; 
     } 
     else { 
      this.sumWithout += td; 
     } 
    }, 

    goTry: function(t1) { 
     try { 
      var counter = 0; 
      for (var i = 0; i < 999999; i++) { 
       counter++; 
      } 
      this.done(t1, true); 
     } 
     catch (err) { 
      console.error(err); 
     } 
    }, 

    goAlone: function(t1) { 
     var counter = 0; 
     for (var i = 0; i < 999999; i++) { 
      counter++; 
     } 
     this.done(t1, false); 
    } 
}; 

var s = new Speedy(); 

यह JSFiddle आप Firebug Lite के कंसोल में उत्पादन दिखाएगा:: निम्नलिखित कोड प्रदर्शन प्रभाव को दर्शाता है http://jsfiddle.net/Mct5N/

+2

अरे वाह आपने वास्तव में प्रश्न का उत्तर दिया ! :) –

+6

उपरोक्त कार्यान्वयन अब काम नहीं करता है (jsFiddle को 'document.writeln' पसंद नहीं है)। यहां एक अद्यतन संस्करण है: http://jsfiddle.net/Mct5N/ – blong

+0

यह अच्छा था लेकिन लगता है कि इस मामले की जांच नहीं हो रही है। –

4

रखने हठधर्मिता एक तरफ और नहीं इस समय यहाँ उत्तर से संतुष्ट होने ...

यदि आपका कोड शायद ही कभी अपवाद फेंकता है, तो अपराधी के चारों ओर एक कोशिश-पकड़ रखकर अच्छा प्रदर्शन होता है क्योंकि अपवाद को पकड़ने या इसे रोकने में कोई अतिरिक्त ओवरहेड नहीं होता है।

यदि कोड आमतौर पर अप्रत्याशित डेटा या उसके जैसा कुछ परिदृश्य के आधार पर अपवाद फेंकता है, तो एक गार्ड विधि रखने से प्रदर्शन में काफी वृद्धि होती है, अपवाद अक्सर होता है।

यदि मैं किसी दृष्टिकोण की सलाह देना चाहता था, तो गहरी घोंसले नहीं होने पर सरल गार्ड ऑपरेटर का उपयोग करें। गहरे घोंसले के मामलों में, एक गार्ड विधि का उपयोग करें जो आवश्यकतानुसार पार हो सकता है।

यहां कुछ परीक्षण है जो मैंने इसे बंद कर दिया है।

http://jsfiddle.net/92cp97pc/6/

परिदृश्य निम्नलिखित लेकिन में छोरों की तुलना कर रहे:

var a; 

// scenario 1 (always throws/catches) 
try { a.b.c.d; } 
catch(ex) { } 

// scenario 2 (about 20 times faster than scenario 1) 
guard(a, 'b', 'c', 'd'); 

// now no exceptions will occur 
a = { b: { c: { d: true } } }; 

// scenario 3 (too fast to measure) 
try { a.b.c.d; } 
catch(ex) { } 

// scenario 4 (.04 times slower than scenario 3) 
guard(a, 'b', 'c', 'd'); 
+0

lodash _.get का सबसे अच्छा गार्ड विधि और लॉनाश का उपयोग आश्चर्यजनक रूप से उपयोगी और तेज़ है। –

0

प्रदर्शन बुद्धिमान कोशिश-पकड़ 20-50% अगर तुलना में धीमी चेक (https://jsperf.com/throw-catch-vs-if-check/1)।

तो, दुर्लभ उपयोग के लिए, इससे कोई फर्क नहीं पड़ता है। भारी उपयोग के लिए, यह कुछ अंतर कर सकता है।

हालांकि, मुझे लगता है कि कोशिश करने के लिए यह बुरा अभ्यास है, अगर यह चेक के जरिए किया जा सकता है, सिवाय इसके कि अगर यह पठनीयता को बहुत कम करता है।

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