Timing R Code with Sys.Time()

Timing R code with Sys.time()

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.

Is Sys.time() the time required for the individual computer to run commands?

Another way is to use proc.time; e.g.

> start_time <- proc.time()
> # some computation
> for (i in 1:10000000) i ^ 3
> proc.time() - start_time
user system elapsed
0.70 0.02 0.72

How can I extract the numeric value from the time difference generated by Sys.time() in R?

You could use system.time():

system.time({mean((rnorm(1e7))^2)})

user system total
0.65 0.00 0.67

or package tictoc:

library(tictoc)
tic()
mean((rnorm(1e7))^2)
#> [1] 0.9998728
toc()
#> 0.66 sec elapsed

For better precision, another alternative is microbenchmark which allows to compare different implementations by running them many times :

microbenchmark::microbenchmark( 
solution_A ={mean((rnorm(1e4))^2)},
solution_B ={
mysum <- 0
for (i in 1:1e4) {
mysum <- mysum + rnorm(1)^2
}
mysum / 1e4
}
)

Unit: microseconds
expr min lq mean median uq max neval cld
solution_A 557.4 570.20 595.785 589.65 597.5 1161.0 100 a
solution_B 16177.3 16918.95 22115.115 17347.85 19315.5 247916.7 100 b

for more details, see this link.

What are 'user' and 'system' times measuring in R system.time(exp) output?

This is discussed in ?proc.time (system.time() returns an object of class "proc.time"):

Details:

‘proc.time’ returns five elements for backwards compatibility, but
its ‘print’ method prints a named vector of length 3. The first
two entries are the total user and system CPU times of the current
R process and any child processes on which it has waited, and the
third entry is the ‘real’ elapsed time since the process was
started.

....and

Value:

....

The definition of ‘user’ and ‘system’ times is from your OS.
Typically it is something like

_The ‘user time’ is the CPU time charged for the execution of user
instructions of the calling process. The ‘system time’ is the CPU
time charged for execution by the system on behalf of the calling
process._

Is difference of Sys.time() a reliable execution time estimate in R?

Here is the output I tried

First example - the calculation output is 2.2... and it's in second.

> start <- Sys.time()
> Sys.sleep(2)
> end <- Sys.time()
> print(paste('Time difference :', end-start))
[1] "Time difference : 2.20864367485046"
> difftime(end, start, units = "mins")
Time difference of 0.03681073 mins

Second example - the calculation output is 1.77... and it is in minutes

> start <- Sys.time()
> x <- matrix(rnorm(7500000), nrow=500, ncol=15000)
> x <- cor(x)
> end <- Sys.time()
> print(paste('Time difference :', end-start))
[1] "Time difference : 1.77510009209315"
> difftime(end, start, units = "mins")
Time difference of 1.7751 mins

You can see that the Time difference you output is actually in minutes but it doesn't state that is minutes or seconds so that it confusing. I recommend you use the difftime() function instead.

How do I time my script in R?

As the others in the comments mentioned before, the simplest way is with system.time. Here's an example code from the system.time manual page

require(stats)
system.time(for(i in 1:100) mad(runif(1000)))

## Not run:
exT <- function(n = 10000) {
# Purpose: Test if system.time works ok; n: loop size
system.time(for(i in 1:n) x <- mean(rt(1000, df = 4)))
}

#-- Try to interrupt one of the following (using Ctrl-C / Escape):
exT() #- about 4 secs on a

2.5GHz Xeon
system.time(exT()) #~ +/- same

On my machine, once the function exT() is called, this is my output:

    user  system elapsed 
2.916 0.004 2.925

And for the function system.time(exT()) I get the following output:

   user  system elapsed 
3.004 0.016 3.026

This means that for the first case the elapsed time is 2.925 seconds and 3.026 for the second.

However, if you want to perform benchmark tests, you should use the package rbenchmark (go here). This is a library which consists of one function:

The library consists of just one function, benchmark, which is a
simple wrapper around system.time.

On the link I've provided, you can see more examples of how to use this package. There are 4 examples there, which are pretty good.

R code for system.time() user time extraction

try the double brackets.

i[["elapsed"]]

Or

i[["user.self"]] if that's what you want, which one are you after?

Or, take the name off the value:

avalue<-i[i]#your example with the name attached
names(avalue)=NULL; #now avalue is just a number again.

get execution time in milliseconds in R

1) Timing is operating-system dependent. On Windows you may only get milliseconds.

2) No need to define tic() and toc(), R has system.time(). Here is an example:

R> system.time(replicate(100, sqrt(seq(1.0, 1.0e6))))
user system elapsed
2.210 0.650 2.867
R>

3) There are excellent add-on packages rbenchmark and microbenchmark.

3.1) rbenchmark is particularly useful for comparison of commands, but can also be used directly:

R> library(rbenchmark)
R> x <- seq(1.0, 1.0e6); benchmark(sqrt(x), log(x))
test replications elapsed relative user.self sys.self user.child sys.child
2 log(x) 100 5.408 2.85835 5.21 0.19 0 0
1 sqrt(x) 100 1.892 1.00000 1.62 0.26 0 0
R>

3.2) microbenchmark excels at highest precision measurements:

R> library(microbenchmark)
R> x <- seq(1.0, 1.0e6); microbenchmark(sqrt(x), log(x))
Unit: nanoseconds
expr min lq median uq max
1 log(x) 50589289 50703132 55283301 55353594 55917216
2 sqrt(x) 15309426 15412135 15452990 20011418 39551819
R>

and this last one, particularly on Linux, already gives you nano-seconds. It can also plot results etc so have a closer look at that package.



Related Topics



Leave a reply



Submit