You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since testthat version 3.0.0 landed, I have experienced a significant increase in the amount of time taken to run unit tests. For example, scran's unit tests have ballooned out from the already-hefty ~280 seconds to an unacceptable 440 seconds. Some forensics suggest that this is caused by an unfortunate interaction between testthat and BiocParallel.
Reproducing the problem
Create a testthat/ directory in your current working directory. Inside testthat/, create a test-snow.R file with:
Then, from your current working directory, start a new R session and run:
library(testthat)
library(scran)
library(BiocParallel)
system.time(test_dir("testthat", package="BiocGenerics"))
## user system elapsed ## 3.463 0.329 15.560
These timings were taken an R environment running testthat 3.0.0. On a similar environment with testthat 2.3.2, I get:
## user system elapsed ## 0.811 0.160 2.321
So it's clearly gotten worse. Some clues can be found by going back to our 3.0.0 environment and omitting the scran load:
library(testthat)
library(BiocParallel)
system.time(test_dir("testthat", package="BiocGenerics"))
## user system elapsed ## 0.962 0.052 2.124
You can see that the mere act of loading scran introduces a several-fold delay, despite the fact that no scran functions are ever used in test-snow.R! This leads us towards the underlying cause...
Diagnosis
The fundamental problem is that testthat 3.0.0 has taken to storing the entire top-level environment in the global options:
BiocParallel then attempts to serialize all symbols in the environment to send to the workers, leading to the observed delay. Incidentally, this is the reason for the package="BiocGenerics" (though any package would probably do here). When package=NULL, the top-level environment is empty as no variables have been defined in the global namespace, so no real damage is done. When package="BiocGenerics", the namespace of the package is used as the environment, presumably causing all symbols in the search path to be included for serialization.
Solution
Adding "topLevelEnvironment" to BiocParallel's blacklist fixes the problem.
library(testthat)
library(scran)
library(BiocParallel)
system.time(test_dir("testthat", package="BiocGenerics"))
## user system elapsed ## 0.897 0.150 2.526
Since testthat version 3.0.0 landed, I have experienced a significant increase in the amount of time taken to run unit tests. For example, scran's unit tests have ballooned out from the already-hefty ~280 seconds to an unacceptable 440 seconds. Some forensics suggest that this is caused by an unfortunate interaction between testthat and BiocParallel.
Reproducing the problem
Create a
testthat/
directory in your current working directory. Insidetestthat/
, create atest-snow.R
file with:Then, from your current working directory, start a new R session and run:
These timings were taken an R environment running testthat 3.0.0. On a similar environment with testthat 2.3.2, I get:
So it's clearly gotten worse. Some clues can be found by going back to our 3.0.0 environment and omitting the scran load:
You can see that the mere act of loading scran introduces a several-fold delay, despite the fact that no scran functions are ever used in
test-snow.R
! This leads us towards the underlying cause...Diagnosis
The fundamental problem is that testthat 3.0.0 has taken to storing the entire top-level environment in the global options:
https://github.com/r-lib/testthat/blob/d0f78e63534516618c84da9114e20dae111093dc/R/test-files.R#L230
This gets sucked into the
global_options
:BiocParallel/R/ErrorHandling.R
Lines 34 to 44 in d3dc1fc
BiocParallel then attempts to serialize all symbols in the environment to send to the workers, leading to the observed delay. Incidentally, this is the reason for the
package="BiocGenerics"
(though any package would probably do here). Whenpackage=NULL
, the top-level environment is empty as no variables have been defined in the global namespace, so no real damage is done. Whenpackage="BiocGenerics"
, the namespace of the package is used as the environment, presumably causing all symbols in the search path to be included for serialization.Solution
Adding
"topLevelEnvironment"
to BiocParallel'sblacklist
fixes the problem.Session information
The text was updated successfully, but these errors were encountered: