2010-11-12 25 views
5

स्कैला का उपयोग करके मैंने एक लिंक की गई सूची में लगभग 100000 नोड्स जोड़े हैं। जब मैं फ़ंक्शन की लंबाई का उपयोग करता हूं, उदाहरण के लिए mylist.length। मुझे 'java.lang.StackOverflowError' त्रुटि मिलती है, क्या मेरी सूची बड़ी प्रक्रिया में है? सूची केवल स्ट्रिंग ऑब्जेक्ट्स है।स्कैला लिंक्ड सूची stackoverflow

उत्तर

11

ऐसा लगता है कि लाइब्रेरी कार्यान्वयन पूंछ-रिकर्सिव override def length: Int = if (isEmpty) 0 else next.length + 1 नहीं है। ऐसा लगता है कि यह कुछ ऐसा है जिस पर मेलिंग सूची पर चर्चा की जा सकती है ताकि यह जांच सके कि कोई वृद्धि टिकट खोला जाना चाहिए या नहीं।

आप इस तरह की लंबाई की गणना कर सकते हैं:

def length[T](l:LinkedList[T], acc:Int=0): Int = 
    if (l.isEmpty) acc else length(l.tail, acc + 1) 
+5

के लिए बेहतर है I सभी एक वृद्धि टिकट के लिए हैं। इस विधि को आसानी से 'ट्रैवर्सबलऑन' में वापस एक गैर-पुनरावर्ती तरीके से कार्यान्वित किया जा सकता है। मैं इसे इस टिप्पणी पंक्ति में भी कार्यान्वित कर सकता हूं: 'def length: int = {var count = 0; foreach {_ => गिनती + = 1}; गिनती} '। 'लीनियरसेक' पर वापस, यह मूल कार्यान्वयन पूरी तरह से पूंछ को पुन: प्राप्त करने के लिए एक निजी सहायक विधि का उपयोग कर बेहतर प्रदर्शन भी प्राप्त कर सकता है। आईएमएचओ, दोनों दृष्टिकोण लिया जाना चाहिए। क्या आप इसे खोलते हैं, या मैं कर सकता हूँ? –

+0

@Daniel कृपया इसे खोलें, क्योंकि आप यहां से अधिक सुझाव प्रदान कर सकते हैं, जैसे आपने यहां किया था। – huynhjl

+1

ठीक है। https://lampsvn.epfl.ch/trac/scala/ticket/3996 –

0

आप जेवीएम में उपलब्ध ढेर/ढेर आकार को बढ़ाने का प्रयास कर सकते हैं।

scala JAVA_OPTS="-Xmx512M -Xms16M -Xss16M" MyClass.scala 

कहाँ

-Xss<size> maximum native stack size for any thread 
-Xms<size> set initial Java heap size 
-Xmx<size> set maximum Java heap size 

This question कुछ और जानकारी है।

यह भी देखें This Scala document

+1

आपका मतलब है 'JAVA_OPTS = "- Xmx512M -Xms16M -Xss16M" scala MyClass.scala'? मेरे खोल को jaVA_OPTS को स्केल कमांड से पहले होना आवश्यक है। – huynhjl

1

स्कैला में, सूची की लंबाई की गणना करना एक ऑर्डर एन ऑपरेशन है, इसलिए आपको इसे टालने का प्रयास करना चाहिए। आप एक ऐरे में स्विच करने पर विचार कर सकते हैं, क्योंकि यह एक स्थिर समय ऑपरेशन है।

+0

'वेक्टर' 'ऐरे' –

0

आप पुष्टि कर सकते हैं कि आप सही मायने में length विधि का उपयोग करने की आवश्यकता है? ऐसा लगता है कि आप अपने उपयोग-मामले के लिए सही संग्रह प्रकार का उपयोग नहीं कर रहे हैं (बिना किसी अतिरिक्त जानकारी के बताना मुश्किल है)। सूची को फोल्ड या पूंछ-रिकर्सिव फ़ंक्शन का उपयोग करने के लिए मैप किए जाने के लिए ऑप्टिमाइज़ किया गया है।

यह कहने के बावजूद, यह पूरी तरह से एक निरीक्षण है जिसे आसानी से मानक पुस्तकालय में पूंछ-पुनरावर्ती कार्य के साथ ठीक किया जा सकता है। उम्मीद है कि हम इसे 2.9.0 के लिए समय पर प्राप्त कर सकते हैं।

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