2015-01-28 15 views
17

Sono ovviamente consapevole del fatto che lo scopo principale dell'oggetto è consentire il subsetting/raggruppamento veloce ecc. E ha molto più senso avere un grande data.table e un sottoinsieme (molto efficientemente) rispetto ad avere un numero (forse piccolo) di oggetti data.table.R - prestazioni lente nella creazione di molti oggetti data.table

Detto questo, di recente ho creato uno script che crea un numero elevato di oggetti data.table e ho notato che le prestazioni diminuiscono all'aumentare del numero di in memoria data.table's in memoria.

Ecco un esempio di ciò che intendo:

n <- 10000 
# create a list containing 10k data.frame's 
system.time(lotsofDFs <- lapply(1:n,FUN=function(i){ data.frame(A=1:10,B=1:10,ID=i)}),gcFirst=T) 
# user system elapsed 
# 2.24 0.00 2.23 
# create a list containing 10k data.table's 
system.time(lotsofDTs <- lapply(1:n,FUN=function(i){ data.table(A=1:10,B=1:10,ID=i)}),gcFirst=T) 
# user system elapsed 
# 5.49 0.01 5.53 
n <- 80000 
# create a list containing 80k data.frame's 
system.time(lotsofDFs <- lapply(1:n,FUN=function(i){ data.frame(A=1:10,B=1:10,ID=i)}),gcFirst=T) 
# user system elapsed 
# 19.42 0.01 19.53 
# create a list containing 80k data.table's 
system.time(lotsofDTs <- lapply(1:n,FUN=function(i){ data.table(A=1:10,B=1:10,ID=i)}),gcFirst=T) 
# user system elapsed 
# 147.03 0.10 147.41 

Come si può notare, mentre data.frame's ora di creazione cresce linearmente con il numero di data.frame's creato, data.table complessità sembra più che lineare.

È previsto?

Ha qualcosa a che fare con l'elenco delle tabelle in memoria (quello che è possibile vedere chiamando la funzione tables())?


Ambiente:

R versione 3.1.2 (su Windows)
data.table 1.9.4


EDIT:

Come sottolineato di @Arun nei commenti, sembra che sia as.data.table(...) comportarsi allo stesso modo di data.frame(...). Infatti, paradossalmente lo as.data.table(data.frame(...)) è più veloce di data.table(...) e il tempo cresce in modo lineare con il numero di oggetti, ad es. :

n <- 10000 
# create a list containing 10k data.table's using as.data.table 
system.time(lotsofDTs <- lapply(1:n,FUN=function(i){ as.data.table(data.frame(A=1:10,B=1:10,ID=i))}),gcFirst=T) 
# user system elapsed 
# 5.04 0.01 5.04 
n <- 80000 
# create a list containing 80k data.table's using as.data.table 
system.time(lotsofDFs <- lapply(1:n,FUN=function(i){ as.data.table(data.frame(A=1:10,B=1:10,ID=i))}),gcFirst=T) 
# user system elapsed 
# 44.94 0.12 45.28 
+1

Questo deve essere abbastanza dipendente dal sistema. Ottengo 2,35 e 2,82 per df e dt rispettivamente sui primi due. –

+6

Hai eseguito 'Rprof()'? Dovrebbe mostrarti il ​​tempo trascorso in 'alloc.col' (sovra-allocazione dei puntatori di colonna) ...: curioso: cosa fai con quei 50. dati.tables? Voglio dire, che tipo di compito richiede molti oggetti? – Arun

+0

'as.data.table (list (...))' si comporta in modo simile a 'data.frame()/as.data.frame()'. Mi porta a pensare che 'data.table()' possa essere migliorato .. – Arun

risposta

1

Si dovrebbe usare setDT:

n <- 80000 
system.time(lotsofDTs <- lapply(1:n,FUN=function(i){setDT(list(A=1:10,B=1:10,ID=matrix(i,10)))}),gcFirst=T) 
# user system elapsed 
# 6.75 0.28 7.17 

system.time(lotsofDFs <- lapply(1:n,FUN=function(i){ data.frame(A=1:10,B=1:10,ID=i)}),gcFirst=T) 
# user system elapsed 
# 32.58 1.40 34.22