Ecco uno strano comportamento in cui sono caduto e non riesco a trovare alcun suggerimento sul perché sia così. Io uso in questo esempio il estimate method of SizeEstimator from Spark, ma non ho trovato alcun problema tecnico nel loro codice quindi mi chiedo perché - se prevedono una buona stima della memoria - il motivo per cui ho questo:Scala: perché Double consuma meno memoria di Floats in questo caso?
stampe uscitaval 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")
la console:
Raw size with doubles: 200
Size with doubles: 96
Raw size with floats: 272
Size with floats: 168
Quindi la mia domanda è piuttosto ingenua: perché i float tendono a prendere più memoria che doppio in questo caso? E perché diventa ancora peggio quando lo trasformo in un iteratore (primo caso, c'è un rapporto del 75% che diventa un rapporto del 50% quando si trasforma in un iteratore!).
(Per avere più contesto, caddi in questo quando si cerca di un'applicazione Spark "ottimizzare" modificando Double
a Float
e scoperto che in realtà ha più memoria avendo carri che raddoppia ...)
PS : non è a causa delle piccole dimensioni del buffer (qui 3), se ho messo 100 invece ottengo:
Raw size with doubles: 3752
Size with doubles: 3200
Raw size with floats: 6152
Size with floats: 5600
e galleggia ancora consumano più memoria ... Ma il rapporto si sono stabilizzati, così sembra che il rapporti diversi nella trasformazione in iteratore devono essere dovuti a un sovraccarico che immagino.
EDIT: Sembra che Product2
è in realtà specializzata solo su Int
, Long
e Double
:
trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product
fare chiunque so perché Float
non viene presa in considerazione? Né Short
che porta a comportamenti strani ...
dispiace I didn vedere l'aggiornamento prima di pubblicare l'anwer. Se lo desideri, posso cancellare la risposta – Odomontois
Nessuna risposta è buona perché hai fornito un link che spiegava perché non è specializzato su tutti i primitivi! È dovuto al numero combinatorio che potrebbe portare ... che in realtà ha senso =) È bello sapere prima di provare a ottimizzare stupidamente come ho provato! –