2014-10-31 35 views
6

我已經寫了一個列表操作函數在F#和Scala上來比較性能。爲了檢驗這一功能,我需要一個列表初始化從1到100000000斯卡拉vs F#列表範圍從1到100000000

F#:

let l = [1..100000000];; 

真:00:00:32.954,CPU:00:00:34.593,GC GEN0:1030 ,gen1:520,gen2:9

這是有效的。

的Scala: 斯卡拉-J-Xmx2G選項

val l = (1 to 10000000).toList // works 

val l = (1 to 100000000).toList // no response long while and finally got java.lang.OutOfMemoryError: Java heap space 

隨着億(億),很長一段時間(1小時)用75%至90%的CPU利用率和2GB的存儲器利用率沒有響應最後得到了 java.lang.OutOfMemoryError:Java堆空間。

我在Scala中做錯了什麼?

+0

您是否嘗試增加內存?可能在生成列表垃圾收集器運行過程並使用90%的CPU時。 – krynio 2014-10-31 11:52:41

+0

對於如此多的元素,Scala的'List'中有很多開銷。你沒有做錯什麼;它只是很多對象分配。我可以在合理的時間內構建這個尺寸的唯一集合看起來就是一個Array。 – Nate 2014-10-31 13:57:55

+0

F#堆大小是否同樣限制爲2GB?假設8字節整數和8字節指針,列表本身佔用至少1.6GB的堆內存。 – lea 2014-10-31 20:41:31

回答

5

注意val l = (1 to 100000000).toList創建一個新的List從原來Range(1 to 100000000)內容,因而是在堆空間不足的機會,以及垃圾收集器的重觸發。按照@ krynio的建議增加-J-Xmx

尚未修改堆大小,請考慮使用迭代器,特別是如果性能測試依賴於列表上的順序迭代;像這樣

(1 to 100000000).iterator 
res0: Iterator[Int] = non-empty iterator 
+0

謝謝@酶。實際上,我在上面的例子中使用了'-J-Xmx2G'。列表操作函數依賴於List的頭部和尾部特徵,特別是'+:'前綴操作符。 – 2014-10-31 12:16:10