Reputation: 3631
Is there a standardized way in R of measuring execution time of function?
Obviously I can take system.time
before and after execution and then take the difference of those, but I would like to know if there is some standardized way or function (would like to not invent the wheel).
I seem to remember that I have once used something like below:
somesysfunction("myfunction(with,arguments)")
> Start time : 2001-01-01 00:00:00 # output of somesysfunction
> "Result" "of" "myfunction" # output of myfunction
> End time : 2001-01-01 00:00:10 # output of somesysfunction
> Total Execution time : 10 seconds # output of somesysfunction
Upvotes: 363
Views: 312935
Reputation: 372
Several answers mention taking the difference of two Sys.time()
s, ie.
start <- Sys.time()
## ... code here ... ##
end <- Sys.time()
end - start
This prints the result in human-readable format, such as "time difference of 2 secs". However, since the unit can vary (from "secs" to "mins" to "days"), it is less useful, say, to compare multiple runtimes on equal footing with this method if their units differ.
For non-interactive purposes, it is preferred to specify the unit of time.
Specifically, Sys.time()
returns a POSIXct
object. Taking the difference of two POSIXct
s give an object of class difftime
, which has a "units" attribute. The `-`
operation, in particular, is defined to use difftime()
when used with a POSIXct
. That is,
time2 - time1
is equivalent to
difftime(time2, time1)
To specify the units attribute, add a units=
argument, eg.
difftime(time2, time1, units="secs")
In summary, one can use Sys.time()
with difftime()
to measure runtimes with a specified unit (secs, mins, etc.), ie.
start <- Sys.time()
## ... code here ... ##
end <- Sys.time()
difftime(end, start, units="secs")
Upvotes: 3
Reputation: 3
Only base package that shows difference in time with units. Units are displayed automatically (secs, mins, ...)
t1 <- Sys.time()
rnorm(10000,0,1)
t2 <- Sys.time()
sprintf("Time took %.2f %s", t2-t1, units(difftime(t2, t1)))
Where %.2f controls the number of decimal places.
Upvotes: 0
Reputation:
library(rbenchmark)
sleep_func <- function() { Sys.sleep(0.5) }
benchmark(sleep_func())
out:
test replications elapsed relative user.self sys.self user.child sys.child
1 sleep_func() 100 50.08 1 0.02 0 NA NA
Upvotes: 0
Reputation: 1367
Based on bench package website:
bench::mark()
from packagebench
is used to benchmark one or a series of expressions, we feel it has a number of advantages over alternatives.
- Always uses the highest precision APIs available for each operating system (often nanoseconds).
- Tracks memory allocations for each expression.
- Tracks the number and type of R garbage collections per expression iteration.
- Verifies equality of expression results by default, to avoid accidentally benchmarking inequivalent code.
- Has
bench::press()
, which allows you to easily perform and combine benchmarks across a large grid of values.- Uses adaptive stopping by default, running each expression for a set amount of time rather than for a specific number of iterations.
- Expressions are run in batches and summary statistics are calculated after filtering out iterations with garbage collections. This allows you to isolate the performance and effects of garbage collection on running time (for more details see Neal 2014).
The times and memory usage are returned as custom objects which have human readable formatting for display (e.g. 104ns) and comparisons (e.g. x$mem_alloc > "10MB").
There is also full support for plotting with ggplot2 including custom scales and formatting.
Use:
bench::mark(log10(5))
#> # A tibble: 1 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 log10(5) 212ns 274ns 2334086. 0B 0
Created on 2021-08-18 by the reprex package (v2.0.1)
Upvotes: 2
Reputation: 4006
Compiling from all anwsers above I came up to use these simplified tic toc functions
tic <- function(){ start.time <<- Sys.time() }
toc <- function(){ round(Sys.time() - start.time) }
to be used as:
tic()
Sys.sleep(3)
toc()
and which prints:
Time difference of 3 secs
Upvotes: 2
Reputation: 111
You can use Sys.time()
. However, when you record the time difference in a table or a csv file, you cannot simply say end - start
. Instead, you should define the unit:
f_name <- function (args*){
start <- Sys.time()
""" You codes here """
end <- Sys.time()
total_time <- as.numeric (end - start, units = "mins") # or secs ...
}
Then you can use total_time
which has a proper format.
Upvotes: 8
Reputation: 1584
Although other solutions are useful for a single function, I recommend the following piece of code where is more general and effective:
Rprof(tf <- "log.log", memory.profiling = TRUE)
# the code you want to profile must be in between
Rprof (NULL) ; print(summaryRprof(tf))
Upvotes: 23
Reputation: 181
Another simple but very powerful way to do this is by using the package profvis
. It doesn't just measure the execution time of your code but gives you a drill down for each function you execute. It can be used for Shiny as well.
library(profvis)
profvis({
#your code here
})
Click here for some examples.
Upvotes: 15
Reputation: 5504
microbenchmark
is a lightweight (~50kB) package and more-or-less a standard way in R for benchmarking multiple expressions and functions:
microbenchmark(myfunction(with,arguments))
For example:
> microbenchmark::microbenchmark(log10(5), log(5)/log(10), times = 10000)
Unit: nanoseconds
expr min lq mean median uq max neval cld
log10(5) 0 0 25.5738 0 1 10265 10000 a
log(5)/log(10) 0 0 28.1838 0 1 10265 10000
Here both the expressions were evaluated 10000 times, with mean execution time being around 25-30 ns.
Upvotes: 57
Reputation: 179388
The built-in function system.time()
will do it.
Use like: system.time(result <- myfunction(with, arguments))
Upvotes: 227
Reputation: 1538
The package "tictoc" gives you a very simple way of measuring execution time. The documentation is in: https://cran.fhcrc.org/web/packages/tictoc/tictoc.pdf.
install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
toc()
To save the elapsed time into a variable you can do:
install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
exectime <- toc()
exectime <- exectime$toc - exectime$tic
Upvotes: 34
Reputation: 662
There is also proc.time()
You can use in the same way as Sys.time
but it gives you a similar result to system.time
.
ptm <- proc.time()
#your function here
proc.time() - ptm
the main difference between using
system.time({ #your function here })
is that the proc.time()
method still does execute your function instead of just measuring the time...
and by the way, I like to use system.time
with {}
inside so you can put a set of things...
Upvotes: 41
Reputation: 3751
Another possible way of doing this would be to use Sys.time():
start.time <- Sys.time()
...Relevent codes...
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
Not the most elegant way to do it, compared to the answere above , but definitely a way to do it.
Upvotes: 332
Reputation: 47541
As Andrie said, system.time()
works fine. For short function I prefer to put replicate()
in it:
system.time( replicate(10000, myfunction(with,arguments) ) )
Upvotes: 66
Reputation: 121057
You can use MATLAB-style tic
-toc
functions, if you prefer. See this other SO question
Upvotes: 14
Reputation: 60452
A slightly nicer way of measuring execution time, is to use the rbenchmark package. This package (easily) allows you to specify how many times to replicate your test and would the relative benchmark should be.
See also a related question at stats.stackexchange
Upvotes: 41