Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timing R code with Sys.time()

Tags:

time

r

while-loop

I can run a piece of code for 5 or 10 seconds using the following code:

period <- 10  ## minimum time (in seconds) that the loop should run for
tm <- Sys.time()  ## starting data & time
while(Sys.time() - tm < period) print(Sys.time())

The code runs just fine for 5 or 10 seconds. But when I replace the period value by 60 for it to run for a minute, the code never stops. What is wrong?

like image 612
Abdul Basit Khan Avatar asked Jul 09 '18 01:07

Abdul Basit Khan


People also ask

How do I subtract time from a DateTime object in R?

Subtraction of date-time objects gives an object of this class, by calling ‘difftime’ with ‘units = "auto"’. Alternatively use proc.time, which measures various times ("user", "system", "elapsed") since you started your R session in seconds.

How do you time a function in a timing loop?

Call the function within a timing loop. Write a stub procedure, essentially by stripping out all the code from your function and just returning from it (but leave all the arguments in). Put the stub into your timing loop and re-time. This measures all the overhead associated with the timing.

Why are system time and user time 0?

"user" time and "system" time are 0, because both CPU and the system kernel are idle. Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question.

How do I calculate the time difference between start_time and end_time?

start_time = Sys.time () Sys.sleep (0.5) end_time = Sys.time () To calculate the difference, we just use a simple subtraction Notice it creates a neat little message for the time difference. whilst the most recent development is available via the tictoc GitHub page. Like Sys.time (), tictoc also gives us ability to nest timings within code.


1 Answers

As soon as elapsed time exceeds 1 minute, the default unit changes from seconds to minutes. So you want to control the unit:

while (difftime(Sys.time(), tm, units = "secs")[[1]] < period)

From ?difftime

 If ‘units = "auto"’, a suitable set of units is chosen, the
 largest possible (excluding ‘"weeks"’) in which all the absolute
 differences are greater than one.

 Subtraction of date-time objects gives an object of this class, by
 calling ‘difftime’ with ‘units = "auto"’.

Alternatively use proc.time, which measures various times ("user", "system", "elapsed") since you started your R session in seconds. We want "elapsed" time, i.e., the wall clock time, so we retrieve the 3rd value of proc.time().

period <- 10
tm <- proc.time()[[3]]
while (proc.time()[[3]] - tm < period) print(proc.time())

If you are confused by the use of [[1]] and [[3]], please consult:

  • How do I extract just the number from a named number (without the name)?
  • How to get a matrix element without the column name in R?

Let me add some user-friendly reproducible examples. Your original code with print inside a loop is quite annoying as it prints thousands of lines onto the screen. I would use Sys.sleep.

test.Sys.time <- function(sleep_time_in_secs) {
  t1 <- Sys.time()
  Sys.sleep(sleep_time_in_secs)
  t2 <- Sys.time()
  ## units = "auto"
  print(t2 - t1)
  ## units = "secs"
  print(difftime(t2, t1, units = "secs"))
  ## use '[[1]]' for clean output
  print(difftime(t2, t1, units = "secs")[[1]])
  }

test.Sys.time(5)
#Time difference of 5.005247 secs
#Time difference of 5.005247 secs
#[1] 5.005247

test.Sys.time(65)
#Time difference of 1.084357 mins
#Time difference of 65.06141 secs
#[1] 65.06141

The "auto" units is very clever. If sleep_time_in_secs = 3605 (more than an hour), the default unit will change to "hours".

Be careful with time units when using Sys.time, or you may be fooled in a benchmarking. Here is a perfect example: Unexpected results in benchmark of read.csv / fread. I had answered it with a now removed comment:

You got a problem with time units. I see that fread is more than 20 times faster. If fread takes 4 seconds to read a file, read.csv takes 80 seconds = 1.33 minutes. Ignoring the units, read.csv is "faster".

Now let's test proc.time.

test.proc.time <- function(sleep_time_in_secs) {
  t1 <- proc.time()
  Sys.sleep(sleep_time_in_secs)
  t2 <- proc.time()
  ## print user, system, elapsed time
  print(t2 - t1)
  ## use '[[3]]' for clean output of elapsed time
  print((t2 - t1)[[3]])
  }

test.proc.time(5)
#   user  system elapsed 
#  0.000   0.000   5.005 
#[1] 5.005

test.proc.time(65)
#   user  system elapsed 
#  0.000   0.000  65.057 
#[1] 65.057

"user" time and "system" time are 0, because both CPU and the system kernel are idle.

like image 69
Zheyuan Li Avatar answered Oct 28 '22 12:10

Zheyuan Li