2012-09-30 10 views
10

मेरे पास अक्सर कार्यों में वैकल्पिक तर्क होते हैं, लेकिन कुछ परीक्षण फ़ायरफ़ॉक्स और सफारी (70-95%) में उनके लिए एक बड़ा प्रदर्शन हिट दिखा रहा है। आश्चर्यजनक रूप से, अगर मैं शाब्दिक मूल्य में अपरिभाषित करता हूं तो कोई दंड नहीं होता है। यहाँ क्या हो रहा है? मैंने सोचा नहीं था कि यह एक स्कोप चेन मुद्दा था क्योंकि वे मूल रूप से फ़ंक्शन के लिए स्थानीय हैं। क्या मैं को प्रत्येक वैकल्पिक तर्क में को परिभाषित करना शुरू कर सकता हूं?अपरिभाषित तर्कों के लिए प्रदर्शन दंड

jsPerf: http://jsperf.com/function-undefined-args/2

+5

@MattWhipple - यह एक दिलचस्प पोस्ट है, लेकिन ओपी के सवाल के साथ इसका क्या संबंध है? (अच्छा सवाल, वैसे, @robC।) –

+0

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

+0

मुझे दृढ़ता से संदेह है कि रनटाइम पैरामीटर गिनती मैच होने पर फ़ंक्शंस को रेखांकित कर रहा है, लेकिन फ़ंक्शन को वास्तविक फ़ंक्शन कॉल के रूप में अन्यथा चला रहा है। तथ्य यह है कि फंक्शन रिटर्न वैल्यू का कोई भी उपयोग नहीं करता है, इसका मतलब यह हो सकता है कि रनटाइम * कुछ भी नहीं * जब पैरामीटर पूरी तरह से आपूर्ति की जाती है। – Pointy

उत्तर

5

इस तरह एक समारोह के लिए:

function threeArgs(x, y, z) { 
    return x + y + z; 
} 

है कि इस तरह कहा जाता है:

threeArgs(1, 2, 3); 

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

इसके अतिरिक्त, यदि कोड थे:

something += 6; 

क्यों:

something += threeArgs(1, 2, 3); 

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

something += 1 + 2 + 3; 

लापता एक पैरामीटर वहाँ है, तथापि, यह हो सकता है कि अनुकूलक जमानत बाहर और एक वास्तविक समारोह कॉल उत्पन्न: यहां तक ​​कि अगर उसने ऐसा नहीं किया, इसे सुरक्षित रूप से समारोह इनलाइन सकता है। इस तरह के एक साधारण समारोह के लिए, फ़ंक्शन कॉल का ओवरहेड प्रदर्शन में बड़े अंतर के लिए आसानी से खाता सकता है।

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

+2

यह एक व्यावहारिक स्पष्टीकरण की तरह लगता है, लेकिन हम कैसे जानते हैं कि यह वास्तव में क्या हो रहा है? – jfriend00

+0

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

+0

"जब कोई पैरामीटर गुम हो जाता है, हालांकि, यह हो सकता है कि ऑप्टिमाइज़र जमानत हो" - क्या आप विस्तार से बता सकते हैं कि ऐसा क्यों है? यदि कोई तर्क गुम है, तो यह अनिर्धारित होने की गारंटी है, इसलिए मुझे लगता है कि यह केवल '1 + 2 + अपरिभाषित 'को रेखांकित करेगा। – pimvdb

2

मुझे लगता है कि क्या समझा सकता है प्रदर्शन अंतर रास्ता तर्क एक समारोह वस्तु को पास किया जाता है: arguments वस्तु के माध्यम से। जब कोई तर्क नहीं गुजरता है, तो जेएस किसी भी दिए गए तर्कों के लिए तर्क ऑब्जेक्ट स्कैन करके शुरू करेगा, जब वे अपरिभाषित होते हैं, arguments प्रोटोटाइप श्रृंखला स्कैन की जाएगी, सभी तरह से Object.prototype तक। यदि उन सभी में वांछित संपत्ति की कमी है, तो जेएस undefined लौटाएगा। , जबकि स्पष्ट रूप से अपरिभाषित गुजर, यह सेट के रूप में सीधे तर्कों पर एक संपत्ति वस्तु:

function foo(arg) 
{ 
    console.log(arguments.hasOwnProperty('0')); 
} 
foo();//false' 
foo('bar');//true 
foo(undefined);//true 

मैं इकट्ठा कि कारण नहीं है क्यों गुजर अपरिभाषित स्पष्ट रूप से तेजी से हो जाता है।

+4

यह एक दिलचस्प विचार है, लेकिन ऐसा लगता है कि औपचारिक पैरामीटर सूची में "arg" प्रतीक घोषित किया गया है, यह हमेशा * स्थानीय संदर्भ होगा। – Pointy

+0

शायद, लेकिन 'console.log (arg === तर्क [0]) में फ़ंक्शन को बदलना;' और 'foo (new date())' लॉग को सही कहते हैं, इसलिए दोनों एक ही चीज़ को संदर्भित करते हैं। मैं वास्तव में कहूंगा कि तर्क स्थानीय 'तर्क' वस्तु की संपत्ति का स्थानीय संदर्भ है। स्कोप स्कैनिंग एक तरफ, प्रोटोटाइप तर्क अभी भी है, है ना? –

+2

ओह हाँ, मैं उस पर सहमत हूं - 'तर्क' वस्तु विचित्र है। मुझे यकीन नहीं है कि यह वास्तव में कैसे प्रभावित करेगा, मेरा मतलब है। दूसरे शब्दों में, चूंकि "तर्क" एक औपचारिक पैरामीटर है, तो इसका मूल्य * हमेशा * तर्क [0] 'का मान है, चाहे वह 'अपरिभाषित' हो या नहीं। – Pointy

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