scala 的 for 推导式什么时候会变得懒惰?
在Python中,我可以做这样的事情:
lazy = ((i,j) for i in range(0,10000) for j in range(0,10000))
sum((1 for i in lazy))
这需要一段时间,但内存使用是恒定的。
scala 中的相同构造:
(for(i<-0 to 10000; j<-i+1 to 10000) yield (i,j)).count((a:(Int,Int)) => true)
过了一会儿,我得到一个 java.lang.OutOfMemoryError
,即使它应该被延迟评估。
In Python, I can do something like this:
lazy = ((i,j) for i in range(0,10000) for j in range(0,10000))
sum((1 for i in lazy))
It will take a while, but the memory use is constant.
The same construct in scala:
(for(i<-0 to 10000; j<-i+1 to 10000) yield (i,j)).count((a:(Int,Int)) => true)
After a while, I get a java.lang.OutOfMemoryError
, even though it should be evaluated lazily.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Scala 的 for 理解本质上并不是懒惰的。它是语法糖*,不会改变两个范围的组合将是渴望的事实。
如果您使用范围的惰性
视图
,则理解的结果也将是惰性的:这里的惰性与for理解无关,而是因为当
flatMap 或
map
(见下文),您会在相同类型的容器中返回结果。因此,for 理解只会保留您输入的内容的惰性(或缺乏)。*对于类似的东西:
Nothing's inherently lazy about Scala's for-comprehension; it's syntactic sugar* which won't change the fact that the combination of your two ranges will be eager.
If you work with lazy
view
s of your ranges, the result of the comprehension will be lazy too:The laziness here is nothing to do with the for-comprehension, but because when
flatMap
ormap
(see below) are called on some type of container, you get back a result in the same type of container. So, the for-comprehension will just preserve the laziness (or lack of) of whatever you put in.*for something like:
懒惰不是来自于理解,而是来自于集合本身。您应该研究集合的严格特征。
但是,对于懒惰的人:-),这里有一个总结:
Iterator
和Stream
是非严格的,view
的选定方法也是如此。任何集合。因此,如果您想要懒惰,请务必先使用.iterator
、.view
或.toStream
您的集合。Laziness comes not from the for-comprehension, but from the collection itself. You should look into the strictness characteristics of the collection.
But, for the lazy :-), here's a summary:
Iterator
andStream
are non-strict, as are selected methods of theview
of any collection. So, if you want laziness, be sure to.iterator
,.view
or.toStream
your collection first.