R - медленная производительность при создании множества объектов data.table

Я, конечно, знаю, что основная цель объекта data.table - позволить быстрому подмножеству/группировке и т.д., и имеет смысл иметь один большой data.table и подмножество (очень эффективно), чем иметь много (возможно, небольших) объектов data.table.

Как я уже сказал, я недавно создал script, который создает много объектов 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


EDIT:

Как отмечено в комментариях @Arun в комментариях, as.data.table(...), похоже, ведет себя аналогично data.frame(...). На самом деле парадоксально as.data.table(data.frame(...)) быстрее, чем data.table(...), и время растет линейно с количеством объектов, например.

n <- 10000
# create a list containing 10k data.table 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 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

Вы должны использовать 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