जावास्क्रिप्ट सरणियों का बड़ा हे


105

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

क्या प्रदर्शन (बड़े ओ समय जटिलता के संदर्भ में) मैं सरणी प्रदर्शन के संबंध में जावास्क्रिप्ट कार्यान्वयन से उम्मीद कर सकता हूं?

मुझे लगता है कि सभी उचित जावास्क्रिप्ट कार्यान्वयन में निम्नलिखित बड़े ओ में से अधिकांश हैं।

  • अभिगमन - O (1)
  • लागू - O (n)
  • Prepending - O (n)
  • सम्मिलन - O (n)
  • विलोपन - O (n)
  • गमागमन - O (1)

जावास्क्रिप्ट का उपयोग करके आप एक सरणी को एक निश्चित आकार में भर सकते हैं new Array(length)सिंटैक्स । (बोनस प्रश्न: इस तरह से एक सरणी बना रहा है ओ (1) या ओ (एन)) यह एक पारंपरिक सरणी की तरह अधिक है, और यदि पूर्व-आकार के सरणी के रूप में उपयोग किया जाता है, तो ओ (1) को जोड़ने की अनुमति दे सकता है। यदि परिपत्र बफ़र तर्क जोड़ा जाता है, तो आप ओ (1) पूर्ववर्ती को प्राप्त कर सकते हैं। यदि एक गतिशील विस्तार सरणी का उपयोग किया जाता है, तो ओ (लॉग एन) उन दोनों के लिए औसत मामला होगा।

क्या मैं अपनी धारणाओं की तुलना में कुछ चीजों के लिए बेहतर प्रदर्शन की उम्मीद कर सकता हूं? मुझे उम्मीद नहीं है कि किसी भी विशिष्टताओं में कुछ भी उल्लिखित है, लेकिन व्यवहार में, यह हो सकता है कि सभी प्रमुख कार्यान्वयन पर्दे के पीछे अनुकूलित सरणियों का उपयोग करें। क्या काम पर गतिशील रूप से एरे या कुछ अन्य प्रदर्शन-बूस्टिंग एल्गोरिदम का विस्तार हो रहा है?

पुनश्च

कारण यह है कि मैं सोच रहा हूँ कि मैं कुछ छँटाई एल्गोरिदम पर शोध कर रहा हूँ, जिनमें से अधिकांश अनुमान लगाने और हटाने के लिए लग रहे हैं कि ओ (1) संचालन जब उनके समग्र बड़े ओ का वर्णन कर रहे हैं।


6
आकार के साथ ऐरे कंस्ट्रक्टर आधुनिक जावास्क्रिप्ट कार्यान्वयन में बहुत बेकार है। यह उस सिंगल पैरामीटर फॉर्म में लगभग कुछ भी नहीं करता है। (यह सेट करता है .lengthलेकिन इसके बारे में है।) ऐरे वास्तव में सादे वस्तु उदाहरणों से बहुत अलग नहीं हैं।
प्वाईंट जूल

3
lengthसंपत्ति सेट करना और पूर्व-आवंटन स्थान दो पूरी तरह से अलग चीजें हैं।
प्वाईंट जूल

1
@ संकेत: जब मैं array[5]एक new Array(10)(ओ) पर सेटिंग की उम्मीद करता हूं तो क्या मैं बहुत ज्यादा उम्मीद कर रहा हूं ?
केंडल फ्रे

1
हालांकि ECMAScript यह परिभाषित नहीं करता है कि एक ऐरे ऑब्जेक्ट को कैसे लागू किया जाता है (यह केवल कुछ अर्थ नियमों को परिभाषित करता है), यह बहुत संभव है कि अलग-अलग कार्यान्वयन अपेक्षित मामलों के लिए अनुकूलन करेंगे (उदाहरण के लिए आकार में कुछ n से कम सरणियों के लिए "वास्तविक सरणी" बैकिंग है) )। मैं कार्यान्वयन के बारे में जानकार नहीं हूं, लेकिन अगर कहीं ऐसा नहीं किया गया तो वाकई आश्चर्य होगा ...

5
@KendallFrey "सर्वश्रेष्ठ उत्तर" में अलग-अलग n / एक्सेस पैटर्न के लिए कुछ jsperf टेस्ट-केस लिखने की संभावना है और देखें कि इसमें क्या आता है ;-)

जवाबों:


111

नोट: जबकि यह उत्तर 2012 में सही था, इंजन आज वस्तुओं और सरणियों दोनों के लिए बहुत अलग आंतरिक अभ्यावेदन का उपयोग करते हैं। यह उत्तर सही हो भी सकता है और नहीं भी।

अधिकांश भाषाओं के विपरीत, जो जावास्क्रिप्ट के साथ सरणियों को लागू करते हैं, जावास्क्रिप्ट जावास्क्रिप्ट में वस्तुएं हैं, और मूल्य एक हैशटेबल में संग्रहीत किए जाते हैं, नियमित ऑब्जेक्ट मूल्यों की तरह। जैसे की:

  • अभिगमन - O (1)
  • लागू करना - Amortized O (1) (कभी-कभी हैशटेबल का आकार बदलना आवश्यक है; आमतौर पर केवल सम्मिलन की आवश्यकता होती है)
  • Prepending - O (n) via unshift, चूंकि इसमें सभी अनुक्रमों को पुन: असाइन करने की आवश्यकता होती है
  • सम्मिलन - यदि मूल्य मौजूद नहीं है तो परिशोधित O (1)। यदि आप मौजूदा मूल्यों (जैसे, का उपयोग करना splice) को शिफ्ट करना चाहते हैं तो ओ (एन )।
  • विचलन - एक मूल्य को हटाने के लिए O (1) को परिशोधित करें, यदि आप सूचकांकों को पुन: असाइन करना चाहते हैं तो O (n) splice
  • गमागमन - O (1)

सामान्य तौर पर, किसी भी कुंजी में किसी भी कुंजी को सेट या अनसेट करना O (1) को परिमित करता है, और वही अनुक्रमणिका के लिए जाता है, चाहे सूचकांक कोई भी हो। किसी भी ऑपरेशन के लिए मौजूदा मानों को फिर से भरने की आवश्यकता होती है, ओ (एन) केवल इसलिए कि आपको सभी प्रभावित मूल्यों को अपडेट करना होगा।


4
ओ (एन) नहीं होना चाहिए? चूंकि सभी सूचकांकों को स्थानांतरित करने की आवश्यकता है। सम्मिलन और विलोपन के लिए समान (मनमाने सूचकांक पर, और तत्वों को शिफ्ट / पतन)।
न्हात्थ

2
इसके अलावा, lengthऐरे म्यूटेशन पर सेट किया गया है, या क्या getयह लंबाई प्राप्त करने जा रहा है और संभवतः इसे याद कर सकता है?
एलेक्स

27
इस जवाब का जिक्र करना अब सही नहीं है। जब तक वे विरल नहीं होते हैं तब तक आधुनिक इंजन Arrays (या अनुक्रमित पूर्णांक कुंजियों के साथ ऑब्जेक्ट्स) को हैशटेबल्स के रूप में संग्रहीत नहीं करते हैं (लेकिन अच्छी तरह से ... C की तरह सरणियाँ)। आपको यहां
बेंजामिन ग्रुएनबाम

4
क्या यह मानक द्वारा परिभाषित किया गया है या क्या यह जेएस इंजन में सिर्फ एक सामान्य कार्यान्वयन है? V8 के बारे में क्या है?
अल्बर्ट

4
@BenjaminGruenbaum यह अच्छा होगा यदि आप थोड़ा सा विकसित कर सकते हैं कि वे कैसे संग्रहीत हैं। या कुछ स्रोत दे।
सीएसएस

1

गारंटी

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

वास्तविकता

उदाहरण के लिए, V8 सरणियों का प्रतिनिधित्व करने के लिए हैशटेबल्स और सरणी सूची दोनों का उपयोग करता है (आज के अनुसार) । इसमें वस्तुओं के लिए विभिन्न विभिन्न अभ्यावेदन भी हैं, इसलिए सरणियों और वस्तुओं की तुलना नहीं की जा सकती है। इसलिए सरणी पहुंच हमेशा O (n) के रूप में बेहतर होती है, और C ++ सरणी पहुंच के समान तेज़ भी हो सकती है । लागू करना O (1) है, जब तक कि आप डेटास्ट्रक्चर के आकार तक नहीं पहुंच जाते हैं और इसे छोटा करना पड़ता है (जो कि O (n) है)। प्रीपेडिंग बदतर है। यदि आप कुछ ऐसा करते हैं तो विलोपन और भी बदतर हो सकता है delete array[index](नहीं!), क्योंकि यह प्रतिनिधित्व को बदलने के लिए इंजन को मजबूर कर सकता है।

सलाह

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

यदि आप वास्तव में एक निश्चित इंजन (और संस्करण) के लिए ऑप्टिमाइज़ करना चाहते हैं, तो पूर्ण उत्तर के लिए इसे सोर्सकोड की जांच करें ।


एक सेकंड के लिए प्रतीक्षा करें, हमारे पास मिश्रित डेटाटाइप्स के साथ सरणियाँ हो सकती हैं? जावास्क्रिप्ट बहुत अच्छा है!
अनुराग

@ अनुराग बिल्कुल, लेकिन 99% मामलों में आपको इस सुविधा की आवश्यकता नहीं होगी
Desiigner
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.