2011-09-16 19 views
7
// Case A 
function Constructor() { 
    this.foo = function() { 
    ... 
    }; 
    ... 
} 

// vs 
// Case B 
function Constructor() { 
    ... 
}; 

Constructor.prototype.foo = function() { 
    ... 
} 

मुख्य कारण लोगों को सलाह देने के प्रोटोटाइप का उपयोग कि .foo प्रोटोटाइप this.foo के रूप में जब अन्य दृष्टिकोण का उपयोग कर कई बार बनाई गई है जहां के मामले में एक बार बनाया जाता है में से एक का उपभोग करता है।बनाने कार्यों अधिक स्मृति

हालांकि एक दुभाषिए इस अनुकूलन कर सकते हैं उम्मीद करेंगे। इसलिए ए

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

क्या आधुनिक जेएस दुभाषिया केस ए को अनुकूलित करते हैं तो फ़ंक्शन foo फ़ंक्शन की केवल एक प्रति है?

उत्तर

8

हाँ, कार्यों बनाने अधिक स्मृति का उपयोग करता है।

... और, नहीं, दुभाषिया केस ए को एक समारोह में अनुकूलित नहीं करते हैं।

कारण the JS scope chain को फ़ंक्शन के प्रत्येक इंस्टेंस को उस समय उपलब्ध चर को कैप्चर करने के लिए आवश्यक है। जिसके अनुसार, की तुलना में वे करते थे, लेकिन मोटे तौर पर क्योंकि बंद कार्यों के निष्पादन एक जोड़ी साल पहले एक ज्ञात समस्या थी modern interpreters मामला एक के बारे में better हैं।

मोज़िला इस कारण से avoid unnecessary closures पर कहता है, लेकिन बंद जेएस डेवलपर टूलकिट में सबसे शक्तिशाली और अक्सर उपयोग किए जाने वाले टूल में से एक है।

अद्यतन: बस this test कि निर्माता के 1M 'उदाहरणों' बनाता भाग गया, Node.js का उपयोग कर (जो वी 8, क्रोम में जे एस दुभाषिया है)। caseA = true के साथ मैं इस स्मृति के उपयोग मिलता है:

{ rss: 212291584, 
vsize: 3279040512, 
heapTotal: 203424416, 
heapUsed: 180715856 } 

और caseA = false साथ मैं इस स्मृति के उपयोग मिलता है: लगभग 3 एक्स द्वारा

{ rss: 73535488, 
vsize: 3149352960, 
heapTotal: 74908960, 
heapUsed: 56308008 } 

तो बंद कार्यों निश्चित रूप से काफी अधिक स्मृति उपभोग कर रहे हैं,। लेकिन पूर्ण अर्थ में, हम प्रति उदाहरण ~ 140-150 बाइट्स के अंतर के बारे में बात कर रहे हैं। (हालांकि यह फ़ंक्शन बनने पर आपके पास मौजूद स्कोप वेरिएबल्स की संख्या के आधार पर बढ़ेगा)।

+0

क्या हमारे पास कुछ संदर्भ हैं जो "बेहतर" और "आधुनिक दुभाषिया" को परिभाषित करते हैं – Raynos

+0

आपके परीक्षण मेरे साथ जो भी मिला है उससे मेल खाता है --- मैंने यह भी परीक्षण करने के लिए फ़ंक्शन के अंदर कुछ बड़े कोड ब्लॉक जोड़े हैं स्मृति गुब्बारा किसी भी तेजी से - और यह नहीं था ... समारोह के अंदर कोड कोई अतिरिक्त स्मृति नहीं लेता है। – gnarf

+0

ओह - और मैं भी पहले स्मृति उपयोग लॉग आउट और परीक्षण के बाद अंतर को मापने के लिए इससे पहले कि वस्तुओं – gnarf

0

जावास्क्रिप्ट दुभाषिया प्रोटोटाइप ऑब्जेक्ट्स को अनुकूलित नहीं कर रहे हैं। इसका केवल एक मामला केवल उनमें से एक है (जो कि कई उदाहरण संदर्भ) है। दूसरी ओर, रचनाकार, नए उदाहरण और उनके भीतर परिभाषित विधियों को बनाते हैं। तो परिभाषा के अनुसार, यह वास्तव में दुभाषिया 'अनुकूलन' का मुद्दा नहीं है बल्कि यह समझने के लिए कि क्या हो रहा है।

एक तरफ ध्यान दें, यदि दुभाषिया उदाहरण विधियों को आजमाया और समेकित करना था, तो यदि आपने कभी किसी विशेष उदाहरण में किसी के मूल्य को बदलने का निर्णय लिया है तो मैं मुद्दों में भाग लेगा (मुझे पसंद है कि सिरदर्द भाषा में नहीं जोड़ा जाएगा) :)

+0

संकलक समारोह का अनुकूलन है, यह हालांकि scopecontext अनुकूलन नहीं करता। – Raynos

+2

कैसे प्रत्येक दुभाषिया डुप्लिकेट संभालती है वास्तव में, हालांकि इस मुद्दे की तरह नहीं लगता है, दुभाषिया कई उदाहरण तरीकों और है कि अंतर अधिक स्मृति – Marlin

+1

की खपत होगी मामले एक के लिए के बीच एक अंतर स्थापित करने के लिए की आवश्यकता होगी, मैं एक संकलक उम्मीद करेंगे देखते हैं कि देखने के लिए कन्स्ट्रक्टर में कोई स्थानीय चर नहीं है इसलिए इसकी परिवर्तनीय वस्तु को उदाहरणों की दायरे श्रृंखला पर रखने की आवश्यकता नहीं है। यदि स्थानीय चर का उपयोग किया जाता है, तो यह तब तक नहीं कर सकता जब तक कि आंतरिक कार्य उन्हें संदर्भित नहीं करता है, तो चर वस्तु को ऑप्टिमाइज़ करने के लिए पर्याप्त स्मार्ट है। भले ही, मैं प्रोटोटाइप दृष्टिकोण का उपयोग अपने तटस्थ और अधिक आसानी से बनाए रखा (निश्चित रूप से आईएमओ) के रूप में करता हूं। – RobG

2

मेरा मानना ​​है कि, नोड में कुछ संक्षिप्त परीक्षण के बाद, कि केस ए और बी दोनों में स्मृति में foo फ़ंक्शन के लिए वास्तविक कोड की केवल एक प्रति है।

केस ए - Constructor() के प्रत्येक निष्पादन के लिए फ़ंक्शन कोड का संदर्भ संग्रहीत करने और उसके वर्तमान निष्पादन दायरे के लिए एक फ़ंक्शन ऑब्जेक्ट बनाया गया है।

प्रकरण बी - वहाँ केवल एक ही गुंजाइश, एक समारोह वस्तु, प्रोटोटाइप के माध्यम से साझा है।

+0

क्या आप अपना टेस्ट कोड पोस्ट कर सकते हैं? मुझे यकीन है कि कुछ अनुकूलन * पार्स * समारोह कोड हर बार से बचने के लिए दुभाषिया के अंदर चल रहा है, लेकिन प्रत्येक के माध्यम से निर्माता से किसी में-गुंजाइश चर के लिए संदर्भ कब्जा करने के लिए है ताकि वे ठीक से हल किया जा सकता समारोह है जब पारित सक्रिय किया गया। – broofa

+0

@broofa - तुम्हारा करने के लिए अपने कोड की तुलना करें, अपने मूल रूप से एक ही ... :) - मैं सिर्फ इतना है कि परीक्षण करने के लिए कुछ और से कोड के 40 लाइनों की तरह फेंक दिया समारोह के अंदर ... – gnarf

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