2010-11-12 10 views
5

Używanie scala Dodałem około 100000 węzłów do połączonej listy. Kiedy używam funkcji length, na przykład mylist.length. Otrzymuję błąd "java.lang.StackOverflowError", czy moja lista jest duża do przetworzenia? Lista jest tylko obiektami typu string.Scala lista powiązana stackoverflow

Odpowiedz

11

Wygląda na to, że implementacja biblioteki nie jest rekursywna w trybie ogonowania override def length: Int = if (isEmpty) 0 else next.length + 1. Wygląda na to, że jest to coś, co można omówić na liście mailingowej, aby sprawdzić, czy należy otworzyć bilet ulepszeń.

Można obliczyć długość takiego:

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

Jestem wszystkim za bilet ulepszenia. Ta metoda może być łatwo zaimplementowana w sposób nierekurencyjny, aż do "TraversableOnce". Mogę nawet zaimplementować go w tym wierszu komentarza: 'def length: Int = {var count = 0; foreach {_ => count + = 1}; count} '. Z powrotem na 'LinearSeq', można uzyskać jeszcze lepszą wydajność przy użyciu prywatnej metody pomocnika, aby oryginalna implementacja była w pełni rekurencyjna. IMHO, oba podejścia powinny zostać podjęte. Czy to otwierasz, czy mogę? –

+0

@Daniel Otwórz to, ponieważ możesz podać więcej sugestii ode mnie, tak jak tutaj. – huynhjl

+1

Ok. https://lampsvn.epfl.ch/trac/scala/ticket/3996 –

0

Możesz spróbować zwiększyć rozmiar stosu/sterty dostępny dla maszyny JVM.

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

Gdzie

-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 ma trochę więcej informacji.

Zobacz także ten This Scala document.

+1

Masz na myśli 'JAVA_OPTS =" - Xmx512M -Xms16M -Xss16M "scala MyClass.scala'? Moja powłoka wymaga, aby JAVA_OPTS była przed poleceniem scala. – huynhjl

1

W programie Scala obliczanie długości listy jest operacją n, dlatego należy jej unikać. Możesz rozważyć przełączenie na Array, ponieważ jest to ciągła operacja czasu.

+0

"Wektor" jest lepszy niż "Tablica" –

0

Czy możesz potwierdzić, że naprawdę trzeba użyć metody length? Wygląda na to, że możesz nie używać prawidłowego typu kolekcji dla twojego przypadku użycia (trudno powiedzieć bez dodatkowych informacji). Listy są zoptymalizowane do mapowania za pomocą fałd lub funkcji rekurencyjnej.

Mimo to jest to absolutnie niedopatrzenie, które można łatwo naprawić w standardowej bibliotece za pomocą funkcji rekursywnej. Mamy nadzieję, że uda nam się zdobyć ją na czas 2.9.0.