2017-08-05 109 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