加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为什么流折叠操作抛出内存异常?

发布时间:2020-12-16 19:12:19 所属栏目:安全 来源:网络整理
导读:我有以下简单的代码 def fib(i:Long,j:Long):Stream[Long] = i #:: fib(j,i+j) (0l /: fib(1,1).take(10000000)) (_+_) 它会抛出OutOfMemmoryError异常. 我无法理解为什么,因为我认为所有部分都使用常量内存,即惰性评估流和foldLeft … 这些代码也不起作用 f
我有以下简单的代码

def fib(i:Long,j:Long):Stream[Long] = i #:: fib(j,i+j)
 (0l /: fib(1,1).take(10000000)) (_+_)

它会抛出OutOfMemmoryError异常.
我无法理解为什么,因为我认为所有部分都使用常量内存,即惰性评估流和foldLeft …

这些代码也不起作用

fib(1,1).take(10000000).sum or max,min e.t.c.

如何正确实现无限流并对其进行迭代操作?

Scala版本:2.9.0

另外scala javadoc说,foldLeft操作对于流是memmory安全的

/** Stream specialization of foldLeft which allows GC to collect
   *  along the way.
   */
  @tailrec
  override final def foldLeft[B](z: B)(op: (B,A) => B): B = {
    if (this.isEmpty) z
    else tail.foldLeft(op(z,head))(op)
  }

编辑:

使用迭代器的实现仍然无用,因为它会抛出${domainName}异常

def fib(i:Long,j:Long): Iterator[Long] = Iterator(i) ++  fib(j,i + j)

如何在Scala中正确定义无限流/迭代器?

EDIT2:
我不关心int溢出,我只是想了解如何在scala中创建无限流/迭代器等而没有副作用.

解决方法

使用Stream而不是Iterator的原因是您不必再次计算系列中的所有小项.但这意味着您需要存储一千万个流节点.不幸的是,它们非常大,因此可能足以溢出默认内存.解决这个问题的唯一现实方法是从更多内存开始(例如scala -J-Xmx2G). (另外,请注意,你将以巨大的幅度溢出Long;斐波纳契系列增长得非常快.)

附:我想到的迭代器实现完全不同;你不是用连接的单例迭代器构建的:

def fib(i: Long,j: Long) = Iterator.iterate((i,j)){ case (a,b) => (b,a+b) }.map(_._1)

现在折叠时,可以放弃过去的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读