14.2 Tools for profiling

14.2.1 Profiling R code

{profvis} and the “flame graph”

library(profvis)
top <- function(){
  # We use profvis::pause() because Sys.sleep() doesn't
  # show in the flame graph
  pause(0.1)
  # Running a series of function with lapply()
  lapply(1:10, function(x){
    x * 10
  })
  # Calling a lower level function
  middle()
}

middle <- function(){
  # Pausing before computing, and calling other functions
  pause(0.2)
  1e4 * 9
  bottom_a()
  bottom_b()
}

# Both will pause and print, _a for 0.5 seconds,
# _b for 2 seconds
bottom_a <- function(){
  pause(0.5)
  print("hey")
}
bottom_b <- function(){
  pause(2)
  print("hey")
}
profvis({
  top()
})

Memory:

  • profvis does indicate memory used, but …

  • {profmem}

14.2.1.1 Identifying bottlenecks

14.2.1.2 Benchmarking R code

""“never start optimizing if you cannot benchmark this optimization”""

Recommend

  • keep a notebook of different implementations that were attempted (for the bottlenecks in your app)

  • {bench}

    • for comparing different implementations
    • checks that outputs are the same
# Multiplying each element of a vector going from 1 to size
# with a for loop
for_loop <- function(size){
  res <- numeric(size)
  for (i in 1:size){
    res[i] <- i * 10
  }
  return(res)
}
# Doing the same thing using a vectorized function
vectorized <- function(size){
  (1:size) * 10
}
res <- bench::mark(
  for_loop = for_loop(1000),
  vectorized = vectorized(1000),
  iterations = 1000
)

14.2.2 Profiling {shiny}

14.2.2.1 Shiny back-end

Can use profvis(print(run_app()))

14.2.3 Profiling web pages