2012-11-21 16 views
6

मैंने कई स्थानों पर पढ़ा है कि फॉर-इन लूप एक सरणी पर लूपिंग से धीमे होते हैं ... हालांकि मैं समझता हूं कि आकार (प्रकार) ब्लॉक में आगे बढ़ना दृश्यों के पीछे जो कुछ भी होता है उसके मुकाबले कहीं भी आसान होता है ऑब्जेक्ट की चाबियाँ, मैं अभी भी उत्सुक हूं, सटीक कारण यह है कि यह बहुत धीमा है ...जावास्क्रिप्ट में धीमा क्यों है?

क्या यह कुंजी प्राप्त करने के लिए एक रिवर्स हैश फ़ंक्शन करना है, और यह प्रक्रिया धीमी है?

+2

हाँ, मुझे लगता है कि सभी चाबियां प्राप्त करने की तुलना में एक सापेक्ष धीमी प्रक्रिया है ... उन्हें प्राप्त नहीं करना;) 'इन ... इन्हें पहले कुंजी को देखना है जबकि सामान्य' लूप, आप लूप वैरिएबल के माध्यम से कुंजी प्रदान कर रहे हैं। –

+2

यहां एक जेएसपीआरएफ परीक्षण है जो दिखाता है कि 'इन ... इन' का रन लगभग 'ऑब्जेक्ट.कीज() '(कम से कम क्रोम में) जैसा ही है: http://jsperf.com/for-in- बनाम-कुंजी-बनाम-के लिए।तो, चाबियाँ प्राप्त करना और/या इससे संबंधित सब कुछ धीमा है और बाहर से चाबियाँ प्रदान करना है। लेकिन यह कार्यान्वयन पर भी निर्भर करता है, जैसे टी.जे. कहते हैं। –

उत्तर

3

किसी भी विशेष इंजन के मामले में इसका वास्तविक जवाब उस इंजन के कार्यान्वयन पर निर्भर करेगा। (जैसा कि अंतर का आकार होगा, यदि कोई हो।)

हालांकि, इनवेरिएंट हैं। उदाहरण के लिए, पर विचार करें:

var obj = {a: "alpha", b: "beta"}; 
var name; 
for (name in obj) { 
    console.log(obj[name]); 
} 

var arr = ["alpha", "beta"]; 
var index; 
for (index = 0; index < arr.length; ++index) { 
    console.log(arr[index]); 
} 

obj के मामले में, इंजन एक तंत्र का उपयोग करने के आप पहले से ही अधिक दोहराया और जो किया है जो गुणों का ट्रैक रखने के लिए नहीं है, साथ ही को छान है लोगों को है गैर-गणना योग्य गुण। उदा।, दृश्यों के पीछे कुछ प्रकार की इटरेटर ऑब्जेक्ट है (और जिस तरह से spec परिभाषित किया गया है, यह एक अस्थायी सरणी भी हो सकता है)।

arr के मामले में, यह नहीं है; आप इसे अपने कोड में, एक बहुत ही सरल, कुशल तरीके से प्रबंधित कर रहे हैं।

प्रत्येक पाश के ब्लॉक की सामग्री समान है: किसी ऑब्जेक्ट पर एक प्रॉपर्टी लुकअप। (बाद के मामले में, सिद्धांत रूप में, एक संख्या-से-स्ट्रिंग रूपांतरण भी है।)

तो मुझे उम्मीद है कि इसका एकमात्र गैर-कार्यान्वयन-विशिष्ट उत्तर यह है: अतिरिक्त ओवरहेड।

1

for..each छोरों iterators and generators का उपयोग करें।

इटरेटर एक वस्तु एक next() विधि पड़ता है। जनरेटर एक कारखाना समारोह है जिसमें yield() अभिव्यक्तियां होती हैं। दोनों संरचनाएं एक पूर्णांक सूचकांक चर से अधिक जटिल हैं।

एक ठेठ for(var i = 0; i < arr.length; i++) पाश में, दो आदेशों में अमल लगभग सभी पुनरावृत्तियों i++ और i < arr हैं। फ़ंक्शन कॉल करने से यह तर्कसंगत रूप से बहुत तेज़ है (next() या yield())।

इसके अलावा, लूप दीक्षा (var i = 0) next() विधि के साथ इटरेटर ऑब्जेक्ट बनाने या जेनरेटर को इटरेटर बनाने के लिए कॉल करने से भी तेज है। हालांकि, यह जावास्क्रिप्ट इंजन के कार्यान्वयन और रचनाकारों पर अत्यधिक निर्भर करता है, ऐसी सामान्य रूप से उपयोग की जाने वाली भाषा सुविधाओं को तेज़ करने के लिए अपनी पूरी कोशिश करते हैं।

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

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