1

Running the following to test how fast runif() runs:

start_time <- Sys.time()
  runif(1)
  end_time <- Sys.time()
  run_times= as.numeric(as.difftime(end_time - start_time, units ="secs"))

It kicks out a fraction of a second for run_times "0.3906578"

But running it in a for loop kicks out 0 each run:

nvec=c(1,100)
uni_time_vec=numeric(length(nvec))
for (i in 1:length(nvec)) {
  start_time <- Sys.time()
  runif(1)                   #hardcoded for testing
  end_time <- Sys.time()
  run_times= as.numeric(as.difftime(end_time - start_time, units ="secs"))
  uni_time_vec[i] = run_times
}

What's happening and how can I get around it?

  • Works fine for me. I can see very small values in `uni_time_vec`.Run `options(digits = 15)` in the console and try again. – Ronak Shah Oct 10 '21 at 05:15
  • Hey Ronak, so the running that line and playing with it more kind of helped, I can get very small values out instead of 0. But it is only working when I create an error (weird). In the for loop I accidently left off a close parentheses "for (i in 1:length(nvec) {" and it kicks back and unexpected error, but completes through. When I add the parentheses back it goes back to returning just 0s. – Dustin Rogers Oct 10 '21 at 09:53

1 Answers1

0

There appears to be some overhead evaluating the code line-wise. If you put it into functions the timings are rather similar with the version without for loop in advantage, what we would expect.

f1 <- function() {
  stm <- Sys.time()
  runif(1)
  Sys.time() - stm
}

f2 <- function() {
  r <- NULL
  for (i in 1) {
    stm <- Sys.time()
    runif(1)                   #hardcoded for testing
    r[i] <- Sys.time() - stm
  }
  r
}

set.seed(42)
R <- 1e5L
t1 <- replicate(R, f1())
t2 <- replicate(R, f2())
lapply(list(t1=t1, t2=t2), summary)
# $t1
# Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
# 5.72e-06 6.44e-06 6.68e-06 7.37e-06 6.68e-06 4.09e-02 
# 
# $t2
# Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
# 5.960e-06 6.680e-06 6.680e-06 7.580e-06 6.910e-06 3.955e-02 

Visualization

u <- range(c(t1, t2))
d1 <- density(r1, from=u[1], to=u[2]); d2 <- density(r2, from=u[1], to=u[2])
plot(d1, log='x', ylim=c(0, max(c(d1$y, d2$y))), col=2, xlab='Sys.time', main='')
lines(d2, col=3)
legend('topright', legend=c('alone', 'in `for` loop'), lty=1, col=2:3)

enter image description here

jay.sf
  • 60,139
  • 8
  • 53
  • 110