2010-11-12 3 views
5

En utilisant scala j'ai ajouté environ 100000 nœuds à une liste chaînée. Quand j'utilise la longueur de la fonction, par exemple mylist.length. Je reçois une erreur 'java.lang.StackOverflowError', ma liste est-elle trop grande pour être traitée? La liste est uniquement des objets chaîne.Scala liste liée stackoverflow

Répondre

11

Il semble que l'implémentation de la bibliothèque ne soit pas récursive en arrière override def length: Int = if (isEmpty) 0 else next.length + 1. Il semble que ce soit quelque chose qui pourrait être discuté sur la liste de diffusion pour vérifier si un ticket d'amélioration devrait être ouvert.

Vous pouvez calculer la longueur comme ceci:

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

Je suis tout pour un billet d'amélioration. Cette méthode peut être facilement implémentée de manière non récursive dans 'TraversableOnce'. Je peux même l'implémenter dans cette ligne de commentaire: 'def longueur: Int = {var count = 0; foreach {_ => compter + = 1}; compte} '. De retour sur 'LinearSeq', on peut obtenir des performances encore meilleures en utilisant une méthode d'aide privée pour rendre l'implémentation originale complètement récursive. À mon humble avis, les deux approches devraient être prises. L'ouvrez-vous, ou puis-je? –

+0

@Daniel S'il vous plaît ouvrez-le, car vous pouvez fournir plus de suggestions que moi, comme vous l'avez fait ici. – huynhjl

+1

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

0

Vous pouvez essayer d'augmenter la taille de pile/segment disponible pour la machine virtuelle Java.

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 a un peu plus d'informations.

Voir aussi This Scala document.

+1

Vous voulez dire 'JAVA_OPTS =" - Xmx512M -Xms16M -Xss16M "scala MyClass.scala'? Mon shell nécessite que JAVA_OPTS soit avant la commande scala. – huynhjl

1

En Scala, le calcul de la longueur d'une liste est une opération de commande n, par conséquent, vous devriez essayer de l'éviter. Vous pourriez envisager de passer à un tableau, car il s'agit d'une opération à temps constant.

+0

'Vector' est préférable à' Array' –

0

Pouvez-vous confirmer que vous avez vraiment besoin d'utiliser la méthode length? Il semble que vous n'utilisiez pas le type de collection correct pour votre cas d'utilisation (difficile à dire sans aucune information supplémentaire). Les listes sont optimisées pour être mappées à l'aide de plis ou d'une fonction récursive. En dépit de cela, c'est absolument un oubli qui peut facilement être résolu dans la bibliothèque standard avec une fonction récursive de la queue. Espérons que nous pouvons l'obtenir à temps pour 2.9.0.