Как стать автором
Обновить
0
0
Владимир @Vladic82

Пользователь

Отправить сообщение
Ещё лучше (чтобы совсем неинтуитивный синтаксис data.table не зубрить) — dtplyr: data.table backend for dplyr
И точно, даже в данном маленьком примере матрица отработала быстрее «быстрых» таблиц:

На моём ПК в данном примере самая быстрая реализация оказалась в пакете matrixStats,
хотя есть ошибка на пределе машинной точности (от -9.095e-13 до 9.095e-13).

library(matrixStats)
start_time <- Sys.time()
a2 <- a^2
bRowSums <- rowSums2(a2)
timediff <- difftime(Sys.time(), start_time)
cat("Расчёт занял: ", timediff, units(timediff))
# Расчёт занял:  0.01400399 secs
identical(b, bRowSums)
# FALSE
summary(b - bRowSums)
#       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
# -9.095e-13 -2.842e-14  0.000e+00  8.440e-17  2.842e-14  9.095e-13


В data.table расчёт дольше, хотя при работе с десятками миллионов записей широких таблиц data.table меня много раз выручал.

library(data.table)
dt <- as.data.table(a)
start_time <- Sys.time()
dt2 <- dt^2
colNames <- names(dt)
dt2[, SUM := rowSums(.SD), .SDcols = colNames]
timediff <- difftime(Sys.time(), start_time)
cat("Расчёт занял: ", timediff, units(timediff))
# Расчёт занял:  0.05101109 secs
identical(dt2$SUM, b)
# TRUE
Согласен, что пример очень неудачный, но благодарю за примеры в пакете, о котором не знал. Сам привык выполнять параллельные расчёты в R в doParallel, который на данном примере вообще не успевал ядра нагрузить, но расчёт через %dopar% выполнился аж за 24 секунды, а при монопотоке как в публикации в 4 секунды:
library(tictoc)
tic()
for(i in 1:dim(a)[1]) {
  b[i] <- sum.of.squares(a[i,])
}
toc()
# 4.16 sec elapsed

library(doParallel)
cl <- makeCluster(16)
registerDoParallel(cl)
tic()
parB <- foreach(i=seq(dim(a)[1]), .inorder = FALSE, .combine = rbind) %dopar% {
                    sum.of.squares(a[i,])
                  }
toc()
# 23.62 sec elapsed


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


library(data.table)
library(matrixStats)
dt <- as.data.table(a)
dt2 <- dt^2
colNames <- names(dt)
tic()
dt2[, SUM := rowSums(.SD), .SDcols = colNames]
toc()
# 0.03 sec elapsed
identical(dt2$SUM, b)
# TRUE


Реализация в пакете future.apply у меня в разы медленнее оказалась на 3950х:

library("future.apply")
plan(multisession)
tic()
bFuture <- future_apply(a, 1, function(x) sum.of.squares(x))
toc()
# 2.61 sec elapsed

Информация

В рейтинге
Не участвует
Откуда
Владивосток, Приморский край, Россия
Зарегистрирован
Активность