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