Lightweight Timer Using a Closure

September 29, 2016
By

(This article was first published on R-SquareD, and kindly contributed to R-bloggers)

Your very own swiss chronograph –

I am always looking for a way to speed up processing in R before giving up and porting to C++.

Chronograph

To find bottlenecks, I used to put timing variables all over code with print statements. When I discovered R6, I immediately created my own timing class to handle this.

library(R6)
Timer = R6Class("Timer",
  ## Public Scope
  public=list(
    initialize = function() {
      # Initialized the timer
      #  and start the clock
      private$ptm = proc.time()
    },
    Lap = function() {
      dif = proc.time() - private$ptm
      private$ptm <<- proc.time()
      print(dif)
    }
  ),
  ## Private Scope
  private=list(
    ptm = NULL
  )
)

t = Timer$new()
for(i in 1:100000) x = i
t$Lap()
##    user  system elapsed 
##    0.02    0.00    0.02
for(i in 1:200000) x = i
t$Lap()
##    user  system elapsed 
##   0.033   0.000   0.035

This works great and I love working with R6, but I want something a little more lightweight for when I’m bouncing between multiple R environments. After racking my brain a little, I found that closures provide great solution to such a simple problem. The closure gives us the data persistance we need and doesn’t require outside packages.

Timer = function() {
  # Initialized the timer
  #  and start the clock
  ptm = proc.time()
  
  function(lab = NULL) {
    dif = proc.time() - ptm
    ptm <<- proc.time()
    print(dif)
  }
}

t = Timer()

rst = c()
for(i in 1:10000) {
  test = c()
  for(j in 1:100) {
    test = c(test, sample(1:0, 1))
  }
  rst = c(rst, sum(test))
}
t()
##    user  system elapsed 
##   6.384   0.000   6.386
rst = c()
for(i in 1:10000) {
  rst = c(rst, sum(sample(1:0, 100, replace=T)))
}
t()
##    user  system elapsed 
##   0.303   0.000   0.303
rst = matrix(nrow = 10000) %>%
  apply(1, FUN = function(x) sum(sample(1:0, 100, replace=T)))
## Error in eval(expr, envir, enclos): could not find function "%>%"
t()
##    user  system elapsed 
##   0.003   0.000   0.005

You could extend this timer to make fancy output and also put conditional development environment checking. If you really wanted to get sophisticated, you could inject the timer into functions automatically. I may write a post in the future on how to do this. Sounds like fun.

To leave a comment for the author, please follow the link and comment on their blog: R-SquareD.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Sponsors

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)