2015-04-17 11 views
8

mi sto leggendo avanzata R programmazione di Hadley e quando tratta la dimensione della memoria per i caratteri si dice questo:Dimensione oggetto per caratteri in R - Come funziona il pool di stringhe R globale?

R ha un pool di stringa globale. Ciò significa che ogni stringa univoca è solo memorizzata in un posto, e quindi i vettori di caratteri occupano meno memoria di quanto ci si potrebbe aspettare.

L'esempio il libro dà è questo:

library(pryr) 
object_size("banana") 
#> 96 B 
object_size(rep("banana", 10)) 
#> 216 B 

Uno degli esercizi di questa sezione è quello di confrontare questi vettori due caratteri:

vec <- lapply(0:50, function(i) c("ba", rep("na", i))) 
str <- lapply(vec, paste0, collapse = "") 

object_size(vec) 
13.4 kB 

object_size(str) 
8.74 kB 

Ora, dal momento che gli stati di passaggio che R ha un pool di stringhe globale e poiché il vettore vec è composto principalmente da ripetizioni di due stringhe ("ba" e "na"), in realtà, intuitivamente, mi aspetto che le dimensioni di vec siano inferiori a la dimensione di str.

Quindi la mia domanda è: come è possibile stimare in modo più accurato la dimensione di questi vettori in anticipo?

+0

Si sta solo pensando ad alta voce, ma scommetto che questo dipende dalla dimensione del pool di stringhe prima dell'istanziazione del vettore. Avete fatto degli esperimenti per testare l'interazione tra la lunghezza del vettore, le lunghezze (cumulative) delle stringhe in quel vettore e se alcune o tutte le stringhe sono state o meno nel pool di stringhe (cioè x <- 'foo ', y = c (' foo ',' bar ')) ecc.? Anche questo potrebbe dipendere dalla piattaforma, dato che ottengo dimensioni completamente diverse per gli oggetti: prima di me 'object_size (vec)' produce '7.42 kB' e' object_size (str) 'produce' 6.89 kB'. – Jthorpe

risposta

1

La differenza chiave è dovuta ai puntatori in vec: ciascuna delle stringhe scalari corte (CHARSXPs) deve essere puntata dal vettore di stringa corrispondente (STRSXP). Si dispone di 1326 di tali puntatori di stringa all'interno di vec, ma solo di 51 in str (un puntatore è probabilmente 8 byte sulla piattaforma). Il pool è per le stringhe scalari (ovvero la cache CHARSXP). Un altro fattore non ovvio è la frammentazione interna, ad es. sul mio sistema, una stringa scalare ha le stesse dimensioni indipendentemente dal fatto che abbia da zero a 7 caratteri, una stringa di 8 caratteri ne richiede di più e così via. Vedere le misure ripetute nella seguente:

unlist(sapply(str, object.size))

[1] 96 96 96 104 104 104 104 120 120 120 120 120 120 120 120 136 136 136 136

[20] 136 136 136 136 152 152 152 152 152 152 152 152 216 216 216 216 216 216 216

[39] 216 216 216 216 216 216 216 216 216 216 216 216 216

Questi sono, tuttavia, i dettagli di implementazione del gestore di memoria di R che potrebbero cambiare e non si dovrebbe dipendere da essi in alcun modo nei programmi utente - con un altro layout di oggetti/gestore di memoria, str potrebbe utilizzare più spazio di vec.