2016-07-16 3 views
116

प्रश्न के बाद Extending String.prototype performance मैं वास्तव में चिंतित हूं, क्योंकि "use strict" को String.prototype विधि में 10 बार बेहतर प्रदर्शन जोड़ा गया है। explanationbergi द्वारा छोटा है और यह मुझे समझाता नहीं है। दो लगभग समान तरीकों के बीच इतना नाटकीय अंतर क्यों है, जो शीर्ष पर "use strict" में भिन्न है? क्या आप इसके बारे में अधिक विस्तार से और सिद्धांत के साथ समझा सकते हैं?क्यों "सख्त उपयोग" इस उदाहरण में प्रदर्शन 10x में सुधार करता है?

String.prototype.count = function(char) { 
 
    var n = 0; 
 
    for (var i = 0; i < this.length; i++) 
 
    if (this[i] == char) n++; 
 
    return n; 
 
}; 
 

 
String.prototype.count_strict = function(char) { 
 
    "use strict"; 
 
    var n = 0; 
 
    for (var i = 0; i < this.length; i++) 
 
    if (this[i] == char) n++; 
 
    return n; 
 
}; 
 
// Here is how I measued speed, using Node.js 6.1.0 
 

 
var STR = '0110101110010110100111010011101010101111110001010110010101011101101010101010111111000'; 
 
var REP = 1e4; 
 

 
console.time('proto'); 
 
for (var i = 0; i < REP; i++) STR.count('1'); 
 
console.timeEnd('proto'); 
 

 
console.time('proto-strict'); 
 
for (var i = 0; i < REP; i++) STR.count_strict('1'); 
 
console.timeEnd('proto-strict');

परिणाम:

proto: 101 ms 
proto-strict: 7.5 ms 
+1

क्या आप इस [i] === char' के साथ परीक्षण कर सकते हैं और देख सकते हैं कि आपको एक ही अंतर मिलता है या नहीं? –

+1

मैंने डीओएम पर्यावरण में इस [i] === char' के साथ परीक्षण किया और परिणाम वही –

+2

बर्गि का स्पष्टीकरण कहता है कि जब आप 'गिनती' फ़ंक्शन को कॉल करते हैं, तो 'यह' पैरामीटर स्ट्रिंग में डालना होगा एक स्ट्रिंग अक्षर के बजाय ऑब्जेक्ट जबकि सख्त मोड में इसे सही ढंग से संचालित करने के लिए नहीं है। यह मामला मेरे बाहर क्यों है, मुझे जवाब में बहुत दिलचस्पी है। –

उत्तर

148

In strict mode, the this context is not forced to be an object. आप एक गैर वस्तु पर एक समारोह कॉल करते हैं, this बस हो जाएगा कि गैर वस्तु।

इसके विपरीत, गैर-सख्त मोड में, this संदर्भ हमेशा किसी ऑब्जेक्ट में लपेटा जाता है यदि यह पहले से कोई ऑब्जेक्ट नहीं है। उदाहरण के लिए, (42).toString()Number ऑब्जेक्ट में पहले 42 को लपेटता है और फिर Number.prototype.toStringNumber ऑब्जेक्ट this संदर्भ के साथ Number.prototype.toString पर कॉल करता है। सख्त मोड में, this संदर्भ को छूटा नहीं गया है और पर 42this संदर्भ के साथ बस कॉल किया गया है।

(function() { 
 
    console.log(typeof this); 
 
}).call(42); // 'object' 
 

 
(function() { 
 
    'use strict'; 
 
    console.log(typeof this); 
 
}).call(42); // 'number'

आपके मामले में, गैर सख्त मोड संस्करण समय रैपिंग और String वस्तु रैपर और वापस में unwrapping आदिम string रों का एक बहुत खर्च करता है। दूसरी तरफ सख्त मोड संस्करण सीधे string पर काम करता है, जो प्रदर्शन में सुधार करता है।

+1

और 'साथ' को हटाने से प्रत्येक चर के लिए थोड़ा सा मदद मिलती है लुकअप आईआईआरसी। – zzzzBov

+2

@zzzzBov गलत है। 'With'' को हटाने से _immensely_ में मदद मिलती है क्योंकि यह ब्राउज़र को यह कारण बताता है कि कौन सी चरणीय अभिव्यक्ति उस चर को संदर्भित करती है। –

+0

सैद्धांतिक रूप से, 'यह। लम्बाई' और 'यह [i]' एक स्ट्रिंग विदेशी ऑब्जेक्ट भी बनाना चाहिए (स्ट्रिंग प्राइमेटिव्स में गुण नहीं हैं), लेकिन संभवतः ब्राउज़र ऐसा नहीं करते हैं। – Oriol

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