Reputation: 5841
I maintain an R package that records the runtimes of many commands, and I am noticing some overhead due to proc.time()
. Is there a faster alternative? I only need to measure things in terms of elapsed time, and I am okay with low precision.
This example workflow shows the overhead of proc.time()
to be around 14% of the total runtime on my machine.
To confirm what I saw, I temporarily removed most of that overhead by deleting this line and replacing this line with a fixed outdated time stamp.
Individual calls to proc.time()
are themselves quite fast, but in my case, they add up.
microbenchmark::microbenchmark(
proc.time()
)
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> proc.time() 1.481 1.494 1.63657 1.501 1.546 11.744 100
Created on 2019-11-22 by the reprex package (v0.3.0)
Session info
devtools::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 3.6.1 (2019-07-05)
#> os macOS Mojave 10.14.6
#> system x86_64, darwin15.6.0
#> ui X11
#> language (EN)
#> collate en_US.UTF-8
#> ctype en_US.UTF-8
#> tz America/Indiana/Indianapolis
#> date 2019-11-22
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date lib source
#> assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0)
#> backports 1.1.5 2019-10-02 [1] CRAN (R 3.6.1)
#> callr 3.3.2 2019-09-22 [1] CRAN (R 3.6.0)
#> cli 1.9.9.9000 2019-11-19 [1] Github (r-lib/cli@24a9bd8)
#> crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0)
#> desc 1.2.0 2019-08-19 [1] Github (r-lib/desc@c860e7b)
#> devtools 2.2.1 2019-09-24 [1] CRAN (R 3.6.0)
#> digest 0.6.22 2019-10-21 [1] CRAN (R 3.6.1)
#> ellipsis 0.3.0 2019-09-20 [1] CRAN (R 3.6.0)
#> evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0)
#> fansi 0.4.0 2018-10-05 [1] CRAN (R 3.6.0)
#> fs 1.3.1 2019-05-06 [1] CRAN (R 3.6.0)
#> glue 1.3.1 2019-03-12 [1] CRAN (R 3.6.0)
#> highr 0.8 2019-03-20 [1] CRAN (R 3.6.0)
#> hms 0.5.2 2019-10-30 [1] CRAN (R 3.6.0)
#> htmltools 0.4.0 2019-10-04 [1] CRAN (R 3.6.0)
#> knitr 1.26 2019-11-12 [1] CRAN (R 3.6.1)
#> magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.0)
#> memoise 1.1.0 2017-04-21 [1] CRAN (R 3.6.0)
#> microbenchmark 1.4-7 2019-09-24 [1] CRAN (R 3.6.0)
#> pillar 1.4.2.9001 2019-08-19 [1] Github (r-lib/pillar@82370d7)
#> pkgbuild 1.0.6 2019-10-09 [1] CRAN (R 3.6.0)
#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.1)
#> pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.6.0)
#> prettyunits 1.0.2 2015-07-13 [1] CRAN (R 3.6.0)
#> processx 3.4.1 2019-07-18 [1] CRAN (R 3.6.0)
#> progress 1.2.2 2019-05-16 [1] CRAN (R 3.6.0)
#> ps 1.3.0 2018-12-21 [1] CRAN (R 3.6.0)
#> R6 2.4.1 2019-11-12 [1] CRAN (R 3.6.1)
#> Rcpp 1.0.3 2019-11-08 [1] CRAN (R 3.6.0)
#> remotes 2.1.0 2019-06-24 [1] CRAN (R 3.6.0)
#> rlang 0.4.1 2019-10-24 [1] CRAN (R 3.6.1)
#> rmarkdown 1.17 2019-11-13 [1] CRAN (R 3.6.0)
#> rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.6.0)
#> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0)
#> stringi 1.4.3 2019-03-12 [1] CRAN (R 3.6.0)
#> stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0)
#> testthat 2.3.0 2019-11-05 [1] CRAN (R 3.6.0)
#> tibble 2.1.3 2019-06-06 [1] CRAN (R 3.6.0)
#> usethis 1.5.1.9000 2019-08-12 [1] Github (r-lib/usethis@b241420)
#> vctrs 0.2.0 2019-07-05 [1] CRAN (R 3.6.0)
#> withr 2.1.2 2018-03-15 [1] CRAN (R 3.6.0)
#> xfun 0.11 2019-11-12 [1] CRAN (R 3.6.1)
#> yaml 2.2.0 2018-07-25 [1] CRAN (R 3.6.0)
#> zeallot 0.1.0 2018-01-28 [1] CRAN (R 3.6.0)
#>
#> [1] /Library/Frameworks/R.framework/Versions/3.6/Resources/library
get_nanotime()
The microbenchmark
package has a get_nanotime()
function, but it is slower than proc.time()
on my machine.
microbenchmark::microbenchmark(
microbenchmark::get_nanotime(),
proc.time()
)
#> Unit: microseconds
#> expr min lq mean median uq max neval
#> microbenchmark::get_nanotime() 5.354 5.5925 6.17782 5.7895 5.937 43.305 100
#> proc.time() 1.490 1.5385 1.78394 1.7505 1.873 8.025 100
Created on 2019-11-22 by the reprex package (v0.3.0)
Upvotes: 2
Views: 96
Reputation: 76460
There are alternatives to base R's proc.time()
function. Two packages that have similar functions are
microbenchmark
, function get_nanotime()
.bench
, function hires_time()
In this comment to the question the OP says that it is
Confirmed:
hires_time()
is > 10x faster on the Mac and Linux machines I have tried.
The tests below were run with R 3.6.1 on Ubuntu 19.04 and the results are not so drastic but bench::hires_time
is the fastest of the three.
library(bench)
library(microbenchmark)
mb <- microbenchmark(
microb = get_nanotime(),
bench = hires_time(),
Rbase = proc.time()
)
print(mb, order = 'median')
#Unit: microseconds
# expr min lq mean median uq max neval cld
# bench 1.107 1.1690 2.03060 1.2320 1.2755 80.835 100 a
# microb 2.006 2.0435 2.46541 2.1200 2.1750 35.431 100 a
# Rbase 2.517 2.6520 2.87621 2.7085 2.7840 16.246 100 a
ggplot2::autoplot(mb)
Upvotes: 1