2012-03-09 14 views
16

कम() विधि के अधिकांश उपयोग मामलों को आसानी से लूप के साथ पुनः लिखा जा सकता है। और जेएसपीआरएफ पर परीक्षण से पता चलता है कि प्रत्येक पुनरावृत्ति के अंदर किए गए संचालन के आधार पर कम() आमतौर पर 60% -75% धीमी होती है।जावास्क्रिप्ट ऐरे को कम करने() विधि का उपयोग करने के लिए कोई वास्तविक लाभ है?

क्या 'कार्यात्मक शैली' में कोड लिखने में सक्षम होने के अलावा, कम करने के लिए कोई वास्तविक कारण है? यदि आपके पास थोड़ा और कोड लिखकर 60% प्रदर्शन लाभ हो सकता है, तो आप कभी भी कम() क्यों उपयोग करेंगे?

संपादित करें: असल में, अन्य कार्यशील तरीकों जैसे कि() और मानचित्र() सभी समान प्रदर्शन दिखाते हैं, कम से कम 60% लूप के लिए सरल से धीमे होते हैं। forloop vs forEach

उत्तर

5
  • आप scoping चाहते हो सकता है:

    यहाँ JSPerf परीक्षण के लिए एक लिंक (समारोह कॉल के साथ) है। उदाहरण के लिए आप कॉलबैक फ़ंक्शंस बनाना चाहते हैं या जावास्क्रिप्ट ऑब्जेक्ट्स के संदर्भ हैं। अधिक जानकारी के लिए, देखें कि क्यों जावास्क्रिप्ट स्कॉप्ड अवरुद्ध नहीं है। [संपादित करें: आधुनिक जावास्क्रिप्ट अब let चर का समर्थन करता है। ESV6 से पहले, जब आपने var वैरिएबल घोषित किया था, तो यह फिसल गया जैसे कि यह फ़ंक्शन कोडब्लॉक के शीर्ष पर लिखा गया था, इसलिए अक्सर आपको कार्यों के रूप में फॉर-लूप के निकायों को लिखना पड़ता था। यह निम्नलिखित अभी भी लागू होता है:] यदि आपके पास कोई फ़ंक्शन लिखा गया है, तो यह तब भी कार्यात्मक शैली का उपयोग कर सकता है जब तक कि यह एक महत्वपूर्ण बाधा न हो।

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

sidenote: इस वाक्य के बीच एक मान्य प्रदर्शन की तुलना है, लेकिन जब वाक्य रचना हाथ में सवाल नहीं है में एक अवैध प्रदर्शन की तुलना:

myArray.map(function(x){return x+1}) 

// ...versus... 

for(var i=0; i<myArray.length; i++) { 
    myArray[i] = myArray[i]+1; 
} 

यह एक वैध प्रदर्शन की तुलना होगा:

myArray.forEach(function(x){return x+1}) 

// ...versus... 

var plusOne = function(x){return x+1}; 
for(var i=0; i<myArray.length; i++) { 
    plusOne(myArray[i]); 
} 

// (may need a side-effect if the compiler is smart enough to optimize this) 

(इसके अलावा अपने संपादित इसके उत्तर में: .forEach() और .map() अधिक स्पष्ट प्रदान करते हैं और आवश्यकता से बचने स्पष्ट लूप int i=0; i<array.length; i++ तर्कों के लिए।)

+2

मैं आपके साथ असहमत हूं कि वैध प्रदर्शन तुलना क्या है। _first_ वैध तुलना है, क्योंकि निश्चित रूप से (आपके उदाहरण के लिए) प्रश्न यह है कि "कौन सी विधि सरणी के प्रत्येक तत्व में जोड़ने के लिए सबसे तेज़ है?", नहीं "कौन सी विधि सबसे तेज़ है लेकिन फ़ंक्शन कॉल का उपयोग न करने वाली कोई विधि अयोग्य है प्रवेश से "। मैं इस बात से सहमत हूं कि यदि आप मानते हैं कि आप स्कोपिंग/क्लोजर उद्देश्यों के लिए वैसे भी एक फ़ंक्शन चाहते हैं तो आप '.reduce()' या 'forfor() 'या जो कुछ भी उपयोग कर सकते हैं। – nnnnnn

+0

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

+0

@EvanYou: '[1,2,3]।के लिए (फ़ंक्शन (x) {setTimeout (फ़ंक्शन() {अलर्ट (x)}, 1000)}) '(अलर्ट 1,2,3) बनाम' var (= i i 0; i <4; i ++) {setTimeout (फ़ंक्शन() {अलर्ट (i)}, 1000)} '(अलर्ट 4,4,4) – ninjagecko

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