2015-01-28 13 views
17

Ich bin mir natürlich bewusst, dass der Hauptzweck von data.table Objekt ist es, schnelle Subsetting/Gruppierung usw. zu ermöglichen, und es macht viel mehr Sinn, eine große data.table und Untermenge zu haben es (sehr effizient) als viele (möglicherweise kleine) data.table Objekte.R - langsame Leistung bei der Erstellung von vielen data.table Objekte

Das gesagt, ich habe vor kurzem ein Skript erstellt, das viele data.table Objekte instanziiert und ich bemerkte, dass die Leistungen verringern, wie die Anzahl der In-Memory data.table's wächst.

Hier ist ein Beispiel dafür, was ich meine:

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 

Wie Sie feststellen können, während data.frame's Erstellung erstellt linear mit der Anzahl der data.frame's wächst, scheint data.table Komplexität mehr als linear.

Wird das erwartet?

Hat das etwas mit der Liste der speicherinternen Tabellen zu tun (die Sie durch Aufruf der Funktion tables() sehen können)?


Umwelt:

R Version 3.1.2 (Windows)
data.table 1.9.4


EDIT:

Wie wies darauf hin, von @Arun in den Kommentaren, as.data.table(...) scheint zu verhalten sich ähnlich wie data.frame(...). Tatsächlich ist paradoxerweise as.data.table(data.frame(...)) schneller als data.table(...) und die Zeit wächst linear mit der Anzahl von Objekten, z. :

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

Dieses hübsche systemabhängig sein muss. Ich bekomme 2,35 und 2,82 für df und dt jeweils auf den ersten beiden. –

+6

Haben Sie 'Rprof()' ausgeführt? Es sollte Ihnen die Zeit zeigen, die Sie in 'alloc.col' verbracht haben (Überzuweisung von Spaltenzeigern) ...: neugierig: Was machen Sie mit diesen 50K data.tables? Ich meine, welche Art von Aufgabe erfordert viele Objekte? – Arun

+0

'as.data.table (liste (...))' führt ähnlich wie 'data.frame()/as.data.frame() 'aus. Führt mich zu der Annahme, dass 'data.table()' verbessert werden könnte. – Arun

Antwort

1

sollten Sie setDT verwenden:

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