这是我陷入的一种奇怪的行为,我找不到任何关于为什么会这样的暗示。我在这个例子中使用了 估计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%!)。
(为了获得更多上下文,我在尝试通过更改来“优化”Spark应用程序时陷入了这种情况 Double
至 Float
并发现它实际上花了更多的内存浮动而不是双打...)
P.S。:这不是由于缓冲区的小尺寸(这里是3),如果我把100而不是我得到:
Raw size with doubles: 3752
Size with doubles: 3200
Raw size with floats: 6152
Size with floats: 5600
并且浮动仍然消耗更多的内存...但是比率已经稳定,所以似乎转换到迭代器的不同比率必然是由于我猜的一些开销。
编辑: 看起来 Product2
实际上只是专门的 Int
, Long
和 Double
:
trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product
有谁知道为什么 Float
没有考虑到?也不 Short
这会导致奇怪的行为......