ここに私が陥った奇妙な振る舞いがあります。なぜこれがこのようなのかのヒントは見つかりません。私は、この例ではestimate method of SizeEstimator from Sparkを使用しますが、私はそう自分のコード内の任意のグリッチを発見していないなぜだろうか - 彼らはメモリの良い推定を提供する場合 - 私はこれ持っている理由:Scala - なぜDoubleはこの場合Floatより少ないメモリを消費しますか?
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
私の質問は非常に素朴です:浮動小数点はなぜこの場合ダブルスよりも多くのメモリを取る傾向がありますか?そして、イテレータに変換すると、それがさらに悪化するのはなぜですか(最初のケースでは、イテレータに変換すると50%の比率になる75%の比率があります)。
(より多くのコンテキストを持っているために、私は... Float
にDouble
を変更することによって、「最適化」スパークアプリケーションをしようとしたときに、このに落ち、それが実際に倍以上山車を持つより多くのメモリを取ったことが判明)
PS :それは、バッファのサイズが小さいのせいではないのです(ここでは3)私が代わりに100を入れた場合、私が取得:
Raw size with doubles: 3752
Size with doubles: 3200
Raw size with floats: 6152
Size with floats: 5600
、まだ多くのメモリを消費浮かぶ...しかし、比率が安定しているので、それがいるようですイテレータへの変換における異なる比率は、私が推測するいくつかのオーバーヘッドのためでなければなりません。
EDIT:Product2
は実際にのみInt
、Long
とDouble
に特化されているようだ:
trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product
Float
を考慮しない理由を誰もが知っていますか?どちらの奇妙な行動につながるShort
...
申し訳ありませんが提示される一方で
(Int,Double)
を意味は、プリミティブJava型
int
とdouble
の2つの分野で構造体として提示されますanwerを掲示する前にアップデートを見ないでください。もしあなたが望むのであれば、私は答えを削除することができます – Odomontoisあなたはすべてのプリミティブに特化していない理由を説明したリンクを提供してくれたので、それは、それが導くコンビナトリアルナンバーによるものです...実際には理にかなっています=)私は試したように愚かに最適化しようとする前に知っておきましょう! –