2010-11-12 18 views
5

Uso de scala He agregado aproximadamente 100000 nodos a una lista vinculada. Cuando uso la longitud de la función, por ejemplo mylist.length. Aparece un error 'java.lang.StackOverflowError', ¿mi lista es grande para procesar? La lista es solo objetos de cadena.Lista enlazada de Scala stackoverflow

Respuesta

11

Parece que la implementación de la biblioteca no es recursiva override def length: Int = if (isEmpty) 0 else next.length + 1. Parece que esto es algo que podría discutirse en la lista de correo para verificar si se debe abrir un ticket de mejora.

Puede calcular la longitud de esta manera:

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

Estoy a favor de un ticket de mejora. Este método se puede implementar fácilmente de una manera no recursiva en todo el camino de regreso en 'TraversableOnce'. Incluso puedo implementarlo en esta línea de comentarios: 'def length: Int = {var count = 0; foreach {_ => count + = 1}; contar} '. De vuelta en 'LinearSeq', se puede obtener un rendimiento aún mejor mediante el uso de un método de ayuda privada para hacer que la implementación original sea completamente recursiva. En mi humilde opinión, ambos enfoques deben tomarse. ¿Lo abres, o puedo? –

+0

@ Daniel Por favor, ábralo, ya que puede proporcionar más sugerencias que yo, al igual que lo hizo aquí. – huynhjl

+1

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

0

Puede intentar aumentar el tamaño de pila/montón disponible para la JVM.

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

Dónde

-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 tiene algo más de información.

Vea también este This Scala document.

+1

Quieres decir 'JAVA_OPTS =" - Xmx512M -Xms16M -Xss16M "scala MyClass.scala'? Mi caparazón requiere que JAVA_OPTS esté antes del comando scala. – huynhjl

1

En Scala, calcular la longitud de una lista es una operación de orden n, por lo tanto, debe tratar de evitarla. Puede considerar cambiar a una matriz, ya que es una operación de tiempo constante.

+0

'Vector' es preferible a' Array' –

0

Se puede confirmar que realmente necesita utilizar el método length? Parece que no está utilizando el tipo de colección correcto para su caso de uso (difícil de distinguir sin información adicional). Las listas están optimizadas para ser mapeadas usando pliegues o una función recursiva de cola.

A pesar de decir esto, esto es absolutamente un descuido que se puede solucionar fácilmente en la biblioteca estándar con una función recursiva de cola. Con suerte, podemos obtenerlo a tiempo para 2.9.0.

Cuestiones relacionadas