2011-08-16 14 views
9

Pensé que R tenía una sobrecarga estándar para almacenar objetos (24 bytes, al parecer, al menos para vectores enteros), pero una simple prueba reveló que es más complejo de lo que creía. Por ejemplo, teniendo los vectores enteros hasta longitud 100 (mediante muestreo aleatorio, con la esperanza de evitar cualquier sneaky sequence compression tricks that might be out there), I encontrado que los diferentes vectores de longitud podrían tener el mismo tamaño, de la siguiente manera:Tamaños de vectores enteros en R

> N = 100 
> V = vector(length = 100) 
> for(L in 1:N){ 
+  z = sample(N, L, replace = TRUE) 
+  V[L] = object.size(z) 
+ } 
> 
> options('width'=88) 
> V 
    [1] 48 48 56 56 72 72 72 72 88 88 88 88 104 104 104 104 168 168 168 168 
[21] 168 168 168 168 168 168 168 168 168 168 168 168 176 176 184 184 192 192 200 200 
[41] 208 208 216 216 224 224 232 232 240 240 248 248 256 256 264 264 272 272 280 280 
[61] 288 288 296 296 304 304 312 312 320 320 328 328 336 336 344 344 352 352 360 360 
[81] 368 368 376 376 384 384 392 392 400 400 408 408 416 416 424 424 432 432 440 440 

Estoy muy impresionado por los valores 152 que se muestran (observación: 152 = 128 + 24, aunque 280 = 256 + 24 no es tan prominente). ¿Alguien puede explicar cómo surgen estas asignaciones? No he podido encontrar una definición clara en la documentación, aunque aparecen celdas V.

+3

Esto podría ser un artefacto de la implementación de 'object.size'. Observe cómo la ayuda lo describe como una estimación ... –

+1

@Nick: Oh no, eso es un poco espeluznante, porque dependo mucho de 'object.size()'. Gracias por el puntero. A medida que leo, surge la incertidumbre debido a posibles problemas de atribución (o incluso codificación). Pero no hay mucho más simple en la vida que los vectores enteros. – Iterator

+0

Estoy de acuerdo, aunque debe tener cuidado de todos modos ya que la reutilización a menudo está oculta (basta con mirar el objeto.tamaño de dos enormes marcos de datos compartiendo todos menos 1 columna) –

Respuesta

12

Incluso si se intenta N <-10.000, todos los valores se producen exactamente el doble, a excepción de vectores de longitud:

  • 5 a 8 (56 bytes)
  • 9 a 12 (72 bytes)
  • 13 a 16 (88 bytes)
  • 17 a 32 (152 bytes)

el hecho de que el número de bytes ocurre dos veces, viene de la sencilla fa ct que la memoria se asigna en pedazos de 8 bytes (a los que se hace referencia como Vcells en ?gc) y los enteros toman solo 4 bytes.

Además de eso, la estructura interna de los objetos en R hace una distinción entre vectores pequeños y grandes para asignar memoria. Los vectores pequeños se asignan en bloques más grandes de aproximadamente 2 Kb, mientras que los vectores más grandes se asignan individualmente. Los vectores 'pequeños' consisten en 6 clases definidas, basadas en la longitud, y pueden almacenar datos vectoriales de hasta 8, 16, 32, 48, 64 y 128 bytes. Como un entero solo ocupa 4 bytes, tiene 2, 4, 8, 12, 16 y 32 enteros que puede almacenar en estas 6 clases. Esto explica el patrón que ves.

El número extra de bytes corresponde al encabezado (que forma las N celdas en ?gc). Si realmente está interesado en todo esto, lea el manual R Internals.

Y, como habrás adivinado, los 24 bytes adicionales son de los encabezados (o Ncélulas). De hecho, es un poco más complicado que eso, pero los detalles exactos se pueden encontrar en el manual R internals

+0

+1 para un respuesta muy perspicaz, y +1 (si pudiera) para usar "distinción". – Iterator

+0

aargh ... eso debería ser "distingue" en lugar de "hace una distinción". Es holandés traducido al inglés. –

+0

No, está bien: la distinción es un sinónimo de distinción. Simplemente no es comúnmente usado por simples mortales. – Iterator

Cuestiones relacionadas