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

时间:2015-01-28 22:39:16

标签: r performance 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

您可以注意到,虽然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

1 个答案:

答案 0 :(得分: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