studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones scala memory apache-spark scala-collections

reales - Scala: ¿por qué Double consume menos memoria que Floats en este caso?



libro de android studio en español pdf (1)

Esto se debe a que Tuple2 está @specialized para Double pero no está especializado en Float .

Eso significa que (Int,Double) se presentará como una estructura con 2 campos de tipos java primitivos int y double , mientras que (Int,Float) se presentará como una estructura con campos int y wrapper tipo java.lang.Float

Más discusión aquí

Aquí hay un comportamiento extraño en el que caí y no puedo encontrar ninguna pista sobre por qué es así. Utilizo en este ejemplo el método de estimación de SizeEstimator de Spark, pero no encontré ninguna falla en su código, así que me pregunto por qué, si proporcionan una buena estimación de la memoria, por qué tengo esto:

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")

La salida de la consola se imprime:

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

Entonces mi pregunta es bastante ingenua: ¿por qué las carrozas tienden a tomar más memoria que las dobles en este caso? Y ¿por qué empeora cuando lo transformo en un iterador (primer caso, hay una proporción del 75% que se convierte en una proporción del 50% cuando se transforma en un iterador).

(Para tener más contexto, caí en esto al tratar de "optimizar" una aplicación Spark cambiando Double to Float y descubrí que en realidad llevaba más memoria teniendo flotantes que dobles ...)

PD: no se debe al tamaño pequeño de los buffers (aquí 3), si pongo 100, obtengo:

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

y las carrozas aún consumen más memoria ... Pero la relación se ha estabilizado, por lo que parece que las diferentes proporciones en la transformación a iterador se deben a una sobrecarga, supongo.

EDITAR: parece que Product2 realidad solo está especializado en Int , Long y Double :

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

¿Alguien sabe por qué Float no se tiene en cuenta? Ni Short que conduce a comportamientos extraños ...