2012-06-26 9 views
6

Tengo una consulta que me devuelve alrededor de 6 millones de filas, que es demasiado grande para procesar todo a la vez en la memoria.¿Cómo puedo aproximar el tamaño de una estructura de datos en scala?

Cada consulta devuelve un Tuple3 [String, Int, java.sql.Timestamp]. Sé que la cadena nunca tiene más de 20 caracteres, UTF8.

¿Cómo puedo calcular el tamaño máximo de una de estas tuplas y, en general, cómo puedo aproximarme al tamaño de una estructura de datos scala como esta?

Tengo 6Gb en la máquina que estoy usando. Sin embargo, los datos se leen desde la base de datos usando scala-query en las listas de scala.

Respuesta

6

Los objetos Scala siguen aproximadamente las mismas reglas que los objetos Java, por lo que cualquier información sobre ellos es precisa. Here is one source, que al menos parece más adecuado para JVM de 32 bits. (Las JVM de 64 bits usan 8 bytes por puntero, lo que generalmente resulta en 4 bytes de sobrecarga adicional más 4 bytes por puntero, pero puede haber menos si la JVM usa punteros comprimidos, lo que hace por defecto ahora, creo).

Supongo que una máquina de 64 bits sin punteros comprimidos (peor caso); entonces un Tuple3 tiene dos punteros (16 bytes) más un Int (4 bytes) más sobrecarga del objeto (~ 12 bytes) redondeado al 8 más cercano, o 32 bytes, más un objeto adicional (8 bytes) como un apéndice para el no- versión especializada de Int. (Tristemente, si utiliza primitivas en tuplas, toma incluso más espacio que cuando usa versiones envueltas). String es 32 bytes, IIRC, más la matriz para los datos que es 16 más 2 por carácter. java.sql.Timestamp necesita almacenar un par de Long s (creo que es), entonces eso es 32 bytes. En total, es del orden de 120 bytes más dos por carácter, que en ~ 20 caracteres es ~ 160 bytes.

Alternativamente, vea this answer para una forma de medir el tamaño de sus objetos directamente. Cuando lo mido de esta manera, obtengo 160 bytes (y mi estimación anterior se ha corregido usando estos datos para que coincida, tuve varios pequeños errores antes).

+0

Buen punto, me olvidé de la sobrecarga adicional en la sobrecarga del objeto String plus. Aún así, no son muchos datos. –

+0

¿Por qué 24 más 2 por carácter en la matriz String? IIRC, una matriz tiene 8 bytes frente a 4 bytes para una matriz, además de los elementos. –

+0

@DanielC.Sobral: hay sobrecarga de objetos más longitud, que es de 16 bytes en una máquina de 64 bits, así que estaba un poco fuera. –

2

¿Cuánta memoria tienes a tu disposición? 6 millones de instancias de un triple realmente no es mucho!

Cada referencia tiene una sobrecarga de 4 u 8 bytes, dependiendo de si está ejecutando 32 o 64 bits (sin "oops" comprimidos, aunque este es el valor predeterminado en JDK7 para montones de menos de 32 GB).

Así que su triple tiene 3 referencias (puede haber más debido a la especialización, por lo que puede obtener 4 refs), su Timestamp es un contenedor (referencia) alrededor de long (8 bytes). Su Int estará especializado (es decir, un int subyacente), por lo que tiene otros 4 bytes. La cadena es 20 x 2 bytes. Así que, básicamente, tiene el peor caso de muy por debajo de 100 bytes por fila; entonces 10 filas por kb, 10,000 filas por Mb. Para que pueda procesar cómodamente sus 6 millones de filas en menos de 1 Gb de pila.

Francamente, creo que he cometido un error aquí porque procesamos diariamente varios millones de filas de aproximadamente veinte campos (incluyendo decimales, cadenas, etc.) cómodamente en este espacio.

+0

¿Alguna retrospectiva al respecto? – matanster

Cuestiones relacionadas