gpt4 book ai didi

scala - Stream#filter 耗尽了 1,000,000 个项目的内存

转载 作者:行者123 更新时间:2023-12-01 02:21:15 25 4
gpt4 key购买 nike

假设我有一个 Stream长度1,000,000全部为 1。

scala> val million = Stream.fill(100000000)(1)
million: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> million filter (x => x % 2 == 0)
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

我收到了 Out of Memory异常(exception)。

然后,我尝试了相同的 filter调用 List .
scala> val y = List.fill(1000000)(1)
y: List[Int] = List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ...

scala> y.filter(x => x % 2 == 0)
res2: List[Int] = List()

然而它成功了。

为什么 Stream#filter这里内存不足,但 List#filter完成得很好?

最后,随着大流,将 filter导致对整个流的非惰性评估?

最佳答案

List的开销- 每个元素有 2 个字段(2 个指针)的单个对象(:: 的实例)。
Stream的开销- Cons的实例(带有 3 个指针)加上一个 Function 的实例( tl: => Stream[A] ) 用于 Stream#tail 的惰性求值每个元素。

因此,您将在 Stream 上花费约 2 倍的内存.

您已经定义了您的 Streamval .或者,您可以定义 milliondef - 在这种情况下,在 filter 之后GC 将删除所有创建的元素,您将恢复内存。

请注意,只有 tailStream很懒,head是严格的,所以 filter严格计算,直到获得满足给定谓词的第一个元素,并且因为您的 Stream 中没有这样的元素filter遍历您的所有 million流并将所有元素放入内存中。

关于scala - Stream#filter 耗尽了 1,000,000 个项目的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20360161/

25 4 0