स्ट्रीम बनाम दृश्य Iterators


136

धाराओं, दृश्य (SeqView), और Iterators में scala के बीच अंतर क्या हैं? यह मेरी समझ है:

  • वे सभी आलसी सूचियाँ हैं।
  • धाराएँ मूल्यों को कैश करती हैं।
  • Iterators केवल एक बार इस्तेमाल किया जा सकता है? आप शुरुआत में वापस नहीं जा सकते हैं और फिर से मूल्य का मूल्यांकन कर सकते हैं?
  • दृश्य के मान कैश नहीं हैं, लेकिन आप उन्हें बार-बार मूल्यांकन कर सकते हैं?

इसलिए यदि मैं ढेर जगह बचाना चाहता हूं, तो क्या मुझे पुनरावृत्तियों का उपयोग करना चाहिए (यदि मैं सूची को फिर से नहीं बदलूंगा) या विचार? धन्यवाद।


7
मैंने इसका उत्तर पहले दिया है, लेकिन इसे कैसे खोजना है? sigh ...
डैनियल सी। सोबरल

जवाबों:


182

पहला, वे सभी गैर-सख्त हैं । कार्यों से संबंधित एक विशेष गणितीय अर्थ है, लेकिन, मूल रूप से, इसका मतलब है कि वे अग्रिम की बजाय ऑन-डिमांड गणना कर रहे हैं।

Streamवास्तव में एक आलसी सूची है। वास्तव में, स्काला में, एक Streama Listजिसका taila है lazy val। एक बार गणना करने के बाद, एक मूल्य गणना की जाती है और पुन: उपयोग किया जाता है। या, जैसा कि आप कहते हैं, मानों को कैश किया गया है।

एक का Iteratorउपयोग केवल एक बार किया जा सकता है क्योंकि यह एक संग्रह में एक ट्रैवर्सल सूचक है , और अपने आप में संग्रह नहीं है। क्या यह स्काला में विशेष बनाता है तथ्य यह है कि आप इस तरह के रूप में परिवर्तन लागू कर सकते हैं mapऔर filterऔर बस एक नया मिलता है Iteratorजो केवल इन परिवर्तनों लागू होगी जब आप अगले तत्व के लिए पूछना।

स्काला पुनरावृत्तियों को प्रदान करता था, जिसे रीसेट किया जा सकता था, लेकिन सामान्य तरीके से समर्थन करना बहुत कठिन है, और उन्होंने संस्करण 2.8.0 नहीं बनाया।

दृश्य को बहुत हद तक डेटाबेस दृश्य की तरह देखा जाता है। यह परिवर्तन की एक श्रृंखला है जो एक "आभासी" संग्रह का उत्पादन करने के लिए एक संग्रह पर लागू होती है। जैसा कि आपने कहा था, जब भी आपको इसमें से तत्वों को लाने की आवश्यकता होती है, तो सभी परिवर्तनों को फिर से लागू किया जाता है।

दोनों Iteratorऔर विचारों में उत्कृष्ट स्मृति विशेषताएं हैं। Streamअच्छा है, लेकिन, स्काला में, इसका मुख्य लाभ अनंत अनुक्रम लिख रहा है (विशेष रूप से अनुक्रम पुनरावर्ती रूप से परिभाषित)। एक कर सकते हैं के सभी रखने से बचने Streamसुनिश्चित करें कि आप अपने लिए एक संदर्भ नहीं रखते बनाकर हालांकि, स्मृति में, head(उदाहरण के लिए, का उपयोग करके defबजाय valपरिभाषित करने के लिए Stream)।

विचारों द्वारा किए गए दंड के कारण, आमतौर पर forceइसे परिवर्तनों को लागू करने के बाद करना चाहिए , या इसे एक दृश्य के रूप में रखना चाहिए यदि केवल कुछ तत्वों को देखने के कुल आकार की तुलना में कभी भी प्राप्त होने की उम्मीद है।


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

5
फाइबोनैचि एक आदर्श उदाहरण से कम है क्योंकि इसमें केवल पिछले 2 पिछले मूल्यों की आवश्यकता होती है, और संपूर्ण स्ट्रीम को रखना एक बेकार है। एकरमैन फ़ंक्शन संभवतः विहित उदाहरण है।
जुरगेन स्ट्रोबेल

4
@ JürgenStrobel Ackermann के परिणामस्वरूप घटिया प्रदर्शन होगा, क्योंकि धाराओं की अनुक्रमित पहुंच O (n) है। लेकिन मैं wrt रिट्रीमेंट से सहमत हूं।
डैनियल सी। सोबरल सेप

9
अरे हाँ। यह स्ट्रीम को किसी भी कैशिंग दृष्टिकोण के लिए एक खराब विकल्प बनाता है।
जुरगेन स्ट्रोबेल

7
यह उत्तर सुपर स्पष्ट है, यह प्रलेखन का हिस्सा होना चाहिए ... ओह, वास्तव में यह है! धन्यवाद डैनियल docs.scala-lang.org/tutorials/FAQ/stream-view-iterator.html
Svend
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.