【发布时间】:2012-01-23 21:22:01
【问题描述】:
据我了解,Stream 保留了最近评估的元素。我猜它不会保留 all 评估的元素(这是不可行的),所以它可能使用了一些内部“缓存”。
正确吗?我可以控制这个缓存的大小和策略吗?
【问题讨论】:
-
您不应将
Streams 视为Iterators,而应将其视为可以延迟评估的Lists。 This question and its answers 可能会有所帮助。
据我了解,Stream 保留了最近评估的元素。我猜它不会保留 all 评估的元素(这是不可行的),所以它可能使用了一些内部“缓存”。
正确吗?我可以控制这个缓存的大小和策略吗?
【问题讨论】:
Streams 视为Iterators,而应将其视为可以延迟评估的Lists。 This question and its answers 可能会有所帮助。
流就像列表一样,根据需要生成其成员。一旦生成了一个元素,它就会保留在流中并重复使用。
例如:
lazy val naturals: Stream[Int] = Stream.cons(0, naturals.map{_ + 1})
会给你一个自然数流。如果我打电话
naturals(5)
如果我调用它,它将生成元素 0-5 并返回 5
naturals(8)
它将重用前 6 个元素并再生成 3 个。
如果您担心内存使用情况,可以使用Stream.drop(num) 生成一个新的流,并从开头删除num 元素,从而允许将截断的元素与旧流一起进行垃圾回收。例如:
naturals(5) //returns 5
val truncated = naturals.drop(4)
truncated(5) //returns 9
【讨论】:
naturals 仍然指向流的头部,前五个元素就不会被垃圾回收。
Stream 对象保留到目前为止已评估/访问的所有引用。 Stream 像 List 一样工作。每个可以从持有的引用中访问的元素,并且已经被访问过至少一次,都不会被垃圾回收。
所以基本上你指向流的指针和你到目前为止评估的内容定义了将被缓存的内容。
【讨论】:
stream 没有有限 内存缓存来存储其元素。听起来像是一种非常消耗内存的方法......
def 定义它们。另见stackoverflow.com/questions/12486762/… 和stackoverflow.com/questions/12529697/…