Разрыв между фактическим временем вычислений и ожидаемым в R - PullRequest
0 голосов
/ 29 мая 2018

У меня есть итеративный алгоритм, который повторяет ту же процедуру на основе ранее обновленных параметров, и пытаюсь оценить истекшее время для всего алгоритма.

Поэтому я измеряю время вычисления (скажем, time1iter) для одной итерации и оцените общее время, умножив его на общее время итерации (nIter * time1iter).

Однако было обнаружено, что между моей оценкой и фактическим временем появляется огромная разница.Например, расчетное время составляет около 8 минут, но это занимает менее 6 минут.

Интересно

  1. , что вообще вызвало этот разрыв, и
  2. как я могу правильно оценить истекшее время для итеративных процедур.

Прилагаю игрушечный пример, где вы можете найти эту «переоценку».

size <- 1000
nIter <- 100

## A single iteration
s_time <- Sys.time()
tmp <- matrix(rnorm(size^2), size, size)
ss <- 0
for(i in 1:size){
  for(j in 1:size){
    ss <- ss + tmp[i,j]
  }
}
time1iter <- difftime(Sys.time(), s_time, units = "secs")
cat(sprintf("Expected time for %d iterations is %3.f secs\n", 
            nIter, time1iter * nIter))

## Main iterations
s_time <- Sys.time()
for(iter in 1:nIter){
  tmp <- matrix(rnorm(size^2), size, size)
  ss <- 0
  for(i in 1:size){
    for(j in 1:size){
      ss <- ss + tmp[i,j]
    }
  }
}
cat(sprintf("Actual elapsed time is %.3f secs\n", 
            difftime(Sys.time(), s_time, units = "secs")))

Результат, который у меня былсоставляет

Ожидаемое время для 100 итераций составляет 17 секунд

Фактическое истекшее время составляет 12,948 секунд

1 Ответ

0 голосов
/ 29 мая 2018

Если мы запускаем цикл несколько раз с увеличением количества итераций, мы получаем довольно линейную зависимость между временем и количеством итераций:

res = data.frame(nIter = seq(1,101,10), time=NA)
for (ni in 1:10){
  nIter <- res[ni, 'nIter']
  s_time <- Sys.time()
  for(iter in 1:nIter){
    tmp <- matrix(rnorm(size^2), size, size)
    ss <- 0
    for(i in 1:size){
      for(j in 1:size){
        ss <- ss + tmp[i,j]
      }
    }
  }
  res[ni, 'time'] <- difftime(Sys.time(), s_time, units = "secs")
}

library(ggplot2)
ggplot(res, aes(nIter, time)) +
  geom_smooth()

enter image description here

Небольшой перехват связан с такими вещами, как накладные расходы на интерпретацию цикла, получение и печать времени.Другими словами, это, кажется, ведет себя так, как и следовало ожидать

lm(time ~ nIter, data = res)    
Coefficients:
(Intercept)        nIter  
   0.009067     0.165585 
...