Measuring function execution time in R
RTimeProfilingR Problem Overview
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
R Solutions
Solution 1 - R
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.
Solution 2 - R
The built-in function system.time()
will do it.
Use like: system.time(result <- myfunction(with, arguments))
Solution 3 - R
As Andrie said, system.time()
works fine. For short function I prefer to put replicate()
in it:
system.time( replicate(10000, myfunction(with,arguments) ) )
Solution 4 - R
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.
Solution 5 - R
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
Solution 6 - R
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...
Solution 7 - R
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
Solution 8 - R
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))
Solution 9 - R
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.
Solution 10 - R
You can use MATLAB-style tic
-toc
functions, if you prefer. See this other SO question
https://stackoverflow.com/questions/1716012/stopwatch-function-in-r/1716344#1716344
Solution 11 - R
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.
Solution 12 - R
Based on bench package website:
> bench::mark()
from package bench
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)
Solution 13 - R
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
Solution 14 - R
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()
measure runtimes with a specified unit (secs, mins, etc.), ie.
start <- Sys.time()
## ... code here ... ##
end <- Sys.time()
difftime(end, start, units="secs")