Scala - 在这种情况下,为什么 Double 消耗的内存比 Floats 少?

标签 scala memory apache-spark scala-collections

这是我遇到的一种奇怪行为,我找不到任何关于为什么会这样的提示。我在这个例子中使用 estimate method of SizeEstimator from Spark但我没有在他们的代码中发现任何故障,所以我想知道为什么 - 如果他们提供了良好的内存估计 - 为什么我有这个:

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

所以我的问题很幼稚:为什么在这种情况下 float 往往比 double 占用更多的内存?以及为什么当我将其转换为迭代器时它会变得更糟(第一种情况,有 75% 的比率在转换为迭代器时变成了 50% 的比率!)。

(为了获得更多上下文,我在尝试通过将 Double 更改为 Float 来“优化” Spark 应用程序时陷入了这种情况,并发现它实际上占用了更多内存 float 比 double ...)

P.S.:这不是由于缓冲区的小尺寸(这里是 3),如果我把 100 改为我得到:

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

并且 float 仍然消耗更多内存......但是比率已经稳定,所以看起来转换到迭代器的不同比率必须是由于我猜的一些开销。

编辑: 看来 Product2 实际上只专注于 IntLongDouble :

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

有人知道为什么不考虑 Float 吗? Short 都不会导致奇怪的行为......

最佳答案

这是因为 Tuple2@specialized 用于 Double 但不是专用于 Float

这意味着 (Int,Double) 将呈现为具有原始 java 类型 intdouble 的 2 个字段的结构,而 (Int,Float) 将显示为具有 int 和包装类型 java.lang.Float 字段的结构

更多讨论here

关于Scala - 在这种情况下,为什么 Double 消耗的内存比 Floats 少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35598035/

相关文章:

Scala 2D 动画库

将多个 OpenCL 缓冲区组合成一个大缓冲区

apache-spark - Spark 2-使用IntelliJ从本地设置特定的 “*-site.xml”或类路径

.net - 什么是 Scala 的 Seq.Span 在 F# 中的等价物?

scala - 如何从 Scala Play 中提供大部分静态页面!应用程序像不同语言的 "About"页面?

c - 我的代码似乎在结束之前没有运行

hadoop - 与Hadoop一起了解Spark

hadoop - Spark 1.2.1 编译汇编工程失败

scala - 定义方法以返回扩展它的类的类型

ios - 由于巨大的 UILabel,应用程序内存不足