rperformancemicrobenchmark

Assess performance of elements within an R function


I know it is possible to estimate the time it takes to complete a function (e.g., with sys.time(), but is there a way to benchmark a function and see which element within the function takes the longest/shortest?

So for example, given the code below, I should be able to performance test the function and determine for run 1, function_long is a bottleneck but for run 2, function_custom is the issue.

function_short <- function(){
  Sys.sleep(2)
}

function_long <- function(){
  sys.sleep(8)
}

function_custom <- function(x){
  sys.sleep(x)
}

function_to_test <- function(x){
  print("Starting function")
  
  print("2 second rest..")
  function_short()
  
  print("8 second rest..")
  function_long()
  
  print(paste0(x), " second rest..")
  function_custom(x)
}

# test these
## run 1
function_to_test(1)

## run 2
function_to_test(10)


Solution

  • Edit: There are a few different options. You could use the built in profiler like this

      function_short <- function(){
        Sys.sleep(2)
      }
      
      function_long <- function(){
        Sys.sleep(8)
      }
      
      function_custom <- function(x){
        Sys.sleep(x)
      }
      
      
    function_custom <- function(x){
      Sys.sleep(x)
    }
    
    function_to_test <- function(x){
      print("Starting function")
      
      print("2 second rest..")
      function_short()
      
      print("8 second rest..")
      function_long()
      
      print(paste0(x), " second rest..")
      function_custom(x)
    } 
    
    
    Rprof('my_fun')
    
    function_to_test(2)
    #> [1] "Starting function"
    #> [1] "2 second rest.."
    #> [1] "8 second rest.."
    #> Warning in print.default(paste0(x), " second rest.."): NAs introduced by
    #> coercion
    #> Error in print.default(paste0(x), " second rest.."): invalid printing digits -2147483648
    
    Rprof(NULL)
    
    
    
    

    Created on 2024-08-16 with reprex v2.1.1

    and in the terminal run 'R CMD Rprof my_fun which catch some of the bottle necks. Alternatively you could do

    script = 'function_short <- function(){
      Sys.sleep(2)
    }
    
    function_long <- function(){
      Sys.sleep(8)
    }
    
    function_custom <- function(x){
      Sys.sleep(x)
    }
    
    
    function_custom <- function(x){
      Sys.sleep(x)
    }
    
    function_to_test <- function(x){
      print("Starting function")
      
      print("2 second rest..")
      function_short()
      
      print("8 second rest..")
      function_long()
      
      print(paste0(x), " second rest..")
      function_custom(x)
    } '
    
    writeLines(script, con = "script.R")
    
    source('script.R')
    
    profvis::profvis(function_to_test(2))
    
    

    Which will open an interactive view of the run time for each parts of the function.

    Created on 2024-08-16 with reprex v2.1.1