2017-08-05 110 views
2

下面的代码提取几乎永远:了解斯卡拉集合执行

val r =(1 to 10000) 
    .map(_ => Seq.fill(10000)(0.0)) 
    .map(_.size) 
    .sum 

虽然这是非常快:

val r =(1 to 10000) 
    .map(_ => Seq.fill(10000)(0.0).size) 
    .sum 

这是为什么?我不会放弃理解执行语句的顺序。在第一种情况下,首先创建大小10000的10000 Seqs,然后将所有这些大小映射为?或者是每个Seq单独映射到大小(并因此被垃圾收集)?

回答

2

你的假设是正确的。在第一个代码片段中,您将创建10.000 Seq实例,并且仅在此之后,在第二次迭代中,这些实例将映射到它们的大小。在第二个片段中,不仅不需要存储每个Seq(因为您只对它们的大小感兴趣),而且也不需要额外的迭代。

为了清楚起见,让我们来看看它没有办法链接:

val range = (1 to 10000) 

val a1 = range.map(_ => Seq.fill(10000)(0.0)) // all collections are maintained in memory 
val a2 = a1.map(_.size) 

val b = range.map(_ => Seq.fill(10000)(0.0).size) // each collection can be thrown away asap