В своей работе я использую несколько таблиц (сведения о клиенте, записи транзакций и т.д.). Некоторые из них очень большие (миллионы строк), я недавно перешел на пакет data.table
(спасибо Мэтью). Однако некоторые из них довольно маленькие (несколько сотен строк и 4/5 столбца) и вызывается несколько раз. Поэтому я начал думать о накладных расходах [.data.table
в извлечения данных, а не в set() значение ting, как уже ясно описано в ?set
, где, независимо от размера таблицы, один элемент устанавливается примерно в 2 микросекунды (в зависимости от процессора).
Однако, похоже, он не эквивалентен set
для получения значения от data.table
, зная точную строку и столбец. Тип петлистой [.data.table
.
library(data.table)
library(microbenchmark)
m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m) # same data used in ?set
> microbenchmark(DF[3450,1] , DT[3450, V1], times=1000) # much more overhead in DT
Unit: microseconds
expr min lq median uq max neval
DF[3450, 1] 32.745 36.166 40.5645 43.497 193.533 1000
DT[3450, V1] 788.791 803.453 813.2270 832.287 5826.982 1000
> microbenchmark(DF$V1[3450], DT[3450, 1, with=F], times=1000) # using atomic vector and
# removing part of DT overhead
Unit: microseconds
expr min lq median uq max neval
DF$V1[3450] 2.933 3.910 5.865 6.354 36.166 1000
DT[3450, 1, with = F] 297.629 303.494 305.938 309.359 1878.632 1000
> microbenchmark(DF$V1[3450], DT$V1[3450], times=1000) # using only atomic vectors
Unit: microseconds
expr min lq median uq max neval
DF$V1[3450] 2.933 2.933 3.421 3.422 40.565 1000 # DF seems still a bit faster (23%)
DT$V1[3450] 3.910 3.911 4.399 4.399 16.128 1000
Последний метод - действительно лучший способ быстро получить один элемент несколько раз. Однако set
еще быстрее
> microbenchmark(set(DT,1L,1L,5L), times=1000)
Unit: microseconds
expr min lq median uq max neval
set(DT, 1L, 1L, 5L) 1.955 1.956 2.444 2.444 24.926 1000
вопрос: если мы можем set
, значение в 2.444 микросекундах не должно быть возможным получить значение в меньшем (или, по крайней мере, аналогичном) количестве времени? Спасибо.
EDIT: добавив еще два варианта:
> microbenchmark(`[.data.frame`(DT,3450,1), DT[["V1"]][3450], times=1000)
Unit: microseconds
expr min lq median uq max neval
`[.data.frame`(DT, 3450, 1) 46.428 47.895 48.383 48.872 2165.509 1000
DT[["V1"]][3450] 20.038 21.504 23.459 24.437 116.316 1000
которые, к сожалению, не быстрее предыдущих попыток.