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

为什么scala的集合默认不是“视图”?

发布时间:2020-12-16 18:52:42 所属栏目:安全 来源:网络整理
导读:在某些情况下,在执行map / filter / …之前将’view’应用于集合会降低性能.然而,这些情况(afaik)很少(例如,当存在单个操作时). 但是大部分时间附加’.view’可以通过阻止创建中间集合来提高性能. 那么,为什么’view’默认不适用于集合?我错过了一些隐藏的
在某些情况下,在执行map / filter / …之前将’view’应用于集合会降低性能.然而,这些情况(afaik)很少(例如,当存在单个操作时).

但是大部分时间附加’.view’可以通过阻止创建中间集合来提高性能.

那么,为什么’view’默认不适用于集合?我错过了一些隐藏的费用吗?

解决方法

简短回答:视图并不总是有益的,默认情况下严格的行为可以防止意外.

考虑一下collections documentation年初的这个片段:

… you might wonder why have strict collections at all? One reason is that performance comparisons do not always favor lazy over strict collections. For smaller collection sizes the added overhead of forming and applying closures in views is often greater than the gain from avoiding the intermediary data structures.

考虑:

List(1,2).map(_ + 1)
// vs
List(1,2).view.map(_ + 1)

该视图仅使用了更多的开销,并且一些粗略的测量结果慢了大约4%(一个很小但很明显的差异).

文件继续说:

A probably more important reason is that evaluation in views can be very confusing if the delayed operations have side effects.

考虑:

for(i <- (1 to 10)) println(i)

如果(1到10)实际上是一个视图(它不是),在被迫这样做之前不会发生任何事情.直截了当的代码可能不是.

更糟糕的是,您最终会遇到令人惊讶的情况,最终您需要重新评估您不需要的代码.拿这个天真的例子:

// Evaluates to List(2,3,4,5),prints "eval" during each evaluation
val list = List(1,2,4).view.map { i => println("eval"); i + 1 }

// For each element in the list,prints the elements that *not* that element (in a view)
def printList[A](list: Traversable[A]): Unit = 
    list foreach { i => list.filter(_ != i) }

因为list是一个视图,所以printList比它应该更多次地评估列表n – 1!

scala> printList(list)
eval
SeqViewMF(...)
eval
SeqViewMF(...)
eval
SeqViewMF(...)
eval
SeqViewMF(...)

现在想象列表没有清楚地标记为视图(即默认情况下的视图).我可以想象许多奇怪的错误或瓶颈是由于意外的重新评估而发生的.

这并不是说严格的评估不会带来它自己的惊喜.这只是一个设计选择,严格的评估不像懒惰评估那样令人惊讶(Paul Phillips可能不同意).

(编辑:李大同)

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

    推荐文章
      热点阅读