1

J'ai ce code:flux Scala itérer et la gestion de la mémoire

val res = Stream // launch the real computation, which alternates E and M steps, updating the computation state 
    .iterate(initCompState)(Base.emIteration) 
    .take(nIteration) 
    .last 

L'idée est de fournir un état initial initCompState, une fonction qui génère un nouvel état de la précédente, exécutez pour nIterations et obtenir la résultat final.

Je ne suis pas interessé par les états intermédiaires, et je voudrais qu'ils soient collectés dès qu'ils ne sont pas nécessaires. De ce que j'ai lu en ligne, Stream conserve des valeurs lorsqu'elles sont définies récursivement, ce qui n'est pas le cas ici.

Mon implémentation est-elle correcte et les états intermédiaires entre les gares initCompState et res sont-ils collectés dès que l'état suivant dans le flux a été calculé?

+2

utiliser plutôt 'Iterator' – cchantep

Répondre

0

Stream est IterableAgain, ce qui signifie qu'il conservera tous les éléments que vous parcourez au cas où vous voudriez les voir à nouveau.

Iterator est plus approprié dans votre cas, vous pouvez passer en revue une fois, donc, il rejette chaque élément dès que vous le regardez. Il n'a pas last, donc, vous auriez à mettre en œuvre vous-même avec quelque chose comme

iterator.foldLeft(Option.empty[Int])((_, n) => Some(n)) 

Vous pouvez également mettre en œuvre simplement vos itérations récursive:

@tailrec 
def iterate(iters: Int, state: State = initCompState): State = if(iters == 0) 
    state 
else 
    iterate(iters - 1, Base.emIteration(state)) 

val result = iterate(nIteration) 
+0

Ainsi, lorsque ils ont dit que vous devriez utiliser def au lieu de val pour éviter de garder tout le flux en mémoire, c'est-à-dire le garder après l'évaluation. Dans les deux cas, lors de l'évaluation, l'ensemble des valeurs calculées est conservé? – vkubicki

+0

Je ne sais pas qui a dit ça ... et pourquoi :) – Dima

+0

Selon la [doc Scala] (http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html) un 'Stream 'est mémoisé seulement tant que quelque chose tient sur la tête. Utiliser 'def' est une façon d'éviter cela. Donc la vraie question est: Est-ce que 'Stream.iterate()()' conserve sa tête si la seule chose retournée est l'itération finale? (Qui, BTW, peut être directement indexé plutôt que 'take (n). Last'). – jwvh