Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to profile the loading of an R package

I have written this R package that takes ages (> 10s, sometimes up to 20-30s!) to load.

Every time the package loads, such as when building the package at the step "** testing if installed package can be loaded", or directly calling library("my.package"), nothing happens for 20s.

This makes everything painfully slow during development: building documentation, building the package, running R check...

Of course I have my suspicions (looking at you, dodgy dependency), but I need to gather evidence before axing it.

Is there a way to profile the loading of the package, in order to identify the cause? Or more generally, how can I figure out what is happening under the hood?

like image 559
asachet Avatar asked Jul 16 '19 09:07

asachet


2 Answers

So an issue with using the detach method from @davide-lorino is that if there are entangled depends or imports, it will fail, and fail hard.

A better method is to use a future backend that loads each of the imports in a clean R session, and time how long it takes to load them via library.

I implemented this in a package that might be useful to others: https://github.com/rmflight/importedPackageTimings

like image 178
rmflight Avatar answered Sep 20 '22 00:09

rmflight


You can determine which library takes the longest to load by benchmarking a call to load each of the libraries that you are testing.

The key is to make sure that you unload the libraries. If you keep the libraries loaded before re-loading them, the library() function will determine that the library has loaded and return out. On a typical benchmark of 100 runs, 1 of them will represent the time it took to load your library, and the remaining 99 will represent the time it took library() to figure out that the library is loaded. The result (duration) will then be an aggregate of the 100 runs, yielding a very small number and almost no variance between the results, like so:

enter image description here

When what you really want looks more like:

enter image description here

Giving us a less surprising result for our efforts.

P.s. the detach_package() function is implemented like this:

detach_package <- function(pkg, character.only = FALSE)
{
  if(!character.only)
  {
    pkg <- deparse(substitute(pkg))
  }
  search_item <- paste("package", pkg, sep = ":")
  while(search_item %in% search())
  {
    detach(search_item, unload = TRUE, character.only = TRUE)
  }
}
like image 23
Davide Lorino Avatar answered Sep 22 '22 00:09

Davide Lorino