簡體   English   中英

Scala - 在這種情況下,為什么Double比Floats消耗更少的內存?

[英]Scala - why Double consume less memory than Floats in this case?

這是我陷入的一種奇怪的行為,我找不到任何關於為什么會這樣的暗示。 我在這個例子中使用了來自Spark的SizeEstimator估計方法,但是我沒有在代碼中發現任何故障,所以我想知道為什么 - 如果它們提供了很好的內存估計 - 為什么我有這個:

val buf1 = new ArrayBuffer[(Int,Double)]
var i = 0
while (i < 3) {
   buf1 += ((i,i.toDouble))
   i += 1
}
System.out.println(s"Raw size with doubles: ${SizeEstimator.estimate(buf1)}")
val ite1 = buf1.toIterator
var size1: Long = 0l
while (ite1.hasNext) {
   val cur = ite1.next()
   size1 += SizeEstimator.estimate(cur)
}
System.out.println(s"Size with doubles: $size1")

val buf2 = new ArrayBuffer[(Int,Float)]
i = 0
while (i < 3) {
   buf2 += ((i,i.toFloat))
   i += 1
}
System.out.println(s"Raw size with floats: ${SizeEstimator.estimate(buf2)}")
val ite2 = buf2.toIterator
var size2: Long = 0l
while (ite2.hasNext) {
   val cur = ite2.next()
   size2 += SizeEstimator.estimate(cur)
 }
 System.out.println(s"Size with floats: $size2")

控制台輸出打印:

Raw size with doubles: 200
Size with doubles: 96
Raw size with floats: 272
Size with floats: 168

所以我的問題很天真:在這種情況下,為什么花車往往會占用更多的內存而不是雙打? 當我將其轉換為迭代器時,為什么會變得更糟(第一種情況,當轉換為迭代器時,有75%的比率變為50%!)。

(為了獲得更多的上下文,我試圖通過將Double更改為Float來“優化”Spark應用程序,並發現它實際上花了更多的浮點數而不是雙倍的內存......

PS:這不是因為緩沖區的小尺寸(這里是3),如果我把100而不是我得到:

Raw size with doubles: 3752
Size with doubles: 3200
Raw size with floats: 6152
Size with floats: 5600

並且浮點數仍然消耗更多的內存......但是這個比率已經穩定下來,所以似乎轉換到迭代器的不同比率必然是由於我猜測的一些開銷。

編輯:似乎Product2實際上只專注於IntLongDouble

trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product

有誰知道為什么沒有考慮Float 無論是Short導致怪異的行為...

這是因為Tuple2@specializedDouble但不專門用於Float

這意味着(Int,Double)將呈現為具有2個原始java類型intdouble字段的結構,而(Int,Float)將呈現為具有int和包裝類型java.lang.Float字段的結構

這里有更多討論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM