R - 在创建大量data.table对象时性能下降

dig*_*All 17 performance r data.table

我当然知道data.table对象的主要目的是允许快速子集化/分组等,并且拥有一个大的data.table子集(非常有效)比拥有许多(可能很小的)data.table对象更有意义.

话虽这么说,我最近创建了一个实例化大量data.table对象的脚本,我注意到随着内存数量的增加,性能会下降data.table's.

这是我的意思的一个例子:

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
Run Code Online (Sandbox Code Playgroud)

正如您所注意到的,虽然data.frame's创建时间与data.frame's创建的数量呈线性增长,但data.table复杂性似乎不仅仅是线性的.

这是预期的吗?

这与内存表列表(您可以通过调用tables()函数看到的那个)有关吗?


环境 :

R版本3.1.2(在Windows上)
data.table 1.9.4


编辑:

正如@Arun在评论中所指出的,as.data.table(...)似乎表现得与之相似data.frame(...).实际上,矛盾的as.data.table(data.frame(...))是比data.table(...)对象的数量更快并且时间随着对象的数量线性增长,例如:

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
Run Code Online (Sandbox Code Playgroud)

fil*_*tor 1

你应该使用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 
Run Code Online (Sandbox Code Playgroud)