1

我有这样的代码:斯卡拉流迭代和内存管理

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

的想法是提供一个初始状态initCompState,即从以前的一个产生新状态的功能,运行此为nIterations,并获得最后结果。

我不是在中间状态感兴趣,并希望他们一旦不需要垃圾回收。从我在线阅读的内容来看,Stream在递归定义时保留了值,这里并不是这种情况。

是我实现正确且一旦流中的下一个状态已经计算收集initCompStateres垃圾之间的中间状态?

+2

而是使用'Iterator' – cchantep

回答

0

StreamIterableAgain,这意味着它将保留所有迭代的元素以防万一你想再次看到它们。

Iterator更适合您的情况,您可以一次扫描一遍,因此,只要您查看它就会丢弃每个元素。它没有last的,所以,你必须给自己的东西实现它像

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

或者,只是实现你的递归迭代:

@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

所以,当他们说你应该使用def而不是val来避免将所有流保存在内存中,这意味着在评估之后保留它。在这两种情况下,评估过程中都保留了整套计算值? – vkubicki

+0

我不知道是谁说的......以及为什么:) – Dima

+0

根据[Scala doc](http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html )只有当头脑中持有某物时,才会记忆“流”。使用'def'是避免这种情况的一种方法。所以真正的问题是:如果返回的唯一东西是最终迭代,Stream.iterate()()是否保持其头部? (它可以直接索引而不是'take(n).last')。 – jwvh