I recently wrote a compute intense function in Rcpp. Now, I would like to port this code to an R package. However, I notice that the code is much (~100x) slower when run inside an R package.
I already read here, that this may have to do with how the function is called. However, this is not a one-time cost. Instead, it scaled with the number of iterations in the Rcpp function (only a single call to Rcpp is made).
Please find a minimally complete verifiable example below. The function below doesn't do anything useful but shows the behavior I am worried about.
How can I troubleshoot this issue?
Steps to recreate package.
Use
Rcpp.package.skeleton
to create a new package skeleton with Rcpp.Add the following example.cpp file to
\src
.example.cpp
#include <Rcpp.h> // [[Rcpp::export]] int example_cpp(Rcpp::IntegerMatrix mat, int iters) { for(int i = 0; i < iters; ++i) { std::vector<int> vec; std::iota(std::begin(vec), std::end(vec), 0); } return 0; }
Add the following example.R file to
\R
.example.R
# @export example <- function(mat, iters) { example_cpp(mat, iters) }
Test the Rcpp function inside/outside the package using the following script.
library(examplePackage) Rcpp::sourceCpp('src/example.cpp') exampleOutside <- function(mat, iters) { example_cpp(mat, iters) } set.seed(42) mat <- replicate(n=1000, sample(1:10)) for(iters in c(1e4, 1e5, 1e6)) { res <- microbenchmark::microbenchmark( example(mat, iters), exampleOutside(mat, iters), times=10 ) print(iters) print(res) }
Output.
[1] 10000
Unit: microseconds
expr min lq mean median uq max neval
example(mat, iters) 629.550 630.977 696.1131 686.488 719.399 858.081 10
exampleOutside(mat, iters) 3.143 4.203 239.7205 5.021 6.981 2340.719 10
[1] 1e+05
Unit: microseconds
expr min lq mean median uq max neval
example(mat, iters) 6512.453 6625.420 6717.6595 6713.2375 6843.519 6921.158 10
exampleOutside(mat, iters) 2.637 3.226 7.6473 4.1205 12.647 16.489 10
[1] 1e+06
Unit: microseconds
expr min lq mean median uq max neval
example(mat, iters) 64091.144 66392.745 67491.8759 68001.405 68609.006 69028.736 10
exampleOutside(mat, iters) 2.885 3.574 10.6664 4.792 17.653 35.927 10