## ----setup, include=FALSE, message=FALSE-------------------------------------- ##library(knitr) library(RTMB) set.seed(1) formals(MakeADFun)$silent <- TRUE ## ----benchmark, echo=FALSE---------------------------------------------------- library(microbenchmark) set.seed(101) ## Loops *must* be fairly long for the caller overhead to vanish x <- rnorm(1e5) y <- rnorm(1e5) ## Benchmark functions *must* return something, or RTMB will optimize it all away! f1_vect <- function(p) { sum(p*x+y) } f1_forloop <- function(p) { z <- 0 for (i in seq_along(x)) { z = z + p*x[i] + y[i] } z } f1_vect_RTMB <- MakeADFun(f1_vect, c(p=1)) f1_forloop_RTMB <- MakeADFun(f1_forloop, c(p=1)) old <- TapeConfig() TapeConfig(vectorize="enable") f1_vect_RTMB2 <- MakeADFun(f1_vect, c(p=1)) invisible(TapeConfig(old)) ## RTMB *must* be given a new argument for each eval, or it will just return the previous value! if (requireNamespace("microbenchmark")) { mm <- microbenchmark(vect = f1_vect(rnorm(1)), vect_RTMB = f1_vect_RTMB$fn(rnorm(1)), vect_RTMB2 = f1_vect_RTMB2$fn(rnorm(1)), forloop = f1_forloop(rnorm(1)), forloop_RTMB = f1_forloop_RTMB$fn(rnorm(1)), times = 100L) } ## ----benchmark-plot, echo = FALSE, fig.width = 8, fig.height = 6, message=FALSE---- if (exists("mm") && requireNamespace("tinyplot")) { par(las=1) mm2 <- transform(as.data.frame(mm), ntime = time/1000, expr = factor(expr, levels = c("vect", "vect_RTMB2", "vect_RTMB", "forloop_RTMB", "forloop"), labels = c("vectorized\nnative R", "TapeConfig\nRTMB", "vectorized\nRTMB", "for loop\nRTMB", "for loop\nnative R")) ) tinyplot::tinyplot(ntime ~ expr, data = mm2, type = "violin", log = "y", trim = TRUE, joint.bw = FALSE, xlab = "", ylab = "time (microseconds)") }