[Rcpp-devel] Alternative way of calling R functions within C++

George Vega Yon g.vegayon at gmail.com
Wed Aug 3 19:50:27 CEST 2016


Hey there,

Looking at some old R code that I have I found this C++ function that
allows evaluating R-written functions within C++ using Rcpp. While this is
no news, the neat thing of it is that it seems to be faster than
Rcpp::Function. Using microbenchmark I compared using Rcpp::function vs my
implementation vs calling the function from R itself and this is what I got

Unit: relative
                expr min  lq     mean median  uq max neval
  cppFuncall(x, fun) 1.3 1.3 1.39    1.3 1.4  83 10000
 RcppFuncall(x, fun) 7.2 7.1 7.13    6.9 6.8  89 10000
              fun(x) 1.0 1.0 1.00    1.0 1.0   1 10000

So, on average, while Rcpp::Function took ~7 times the R call took, my
implementation took ~1.3 times. To be sure I was not breaking anything I
ran the example using valgrind and there is no memory leak. The source code
for the test follows:

-------- example_calling_r_functions.cpp ----

#include <Rinternals.h>
#include <Rcpp.h>

// [[Rcpp::export]]
SEXP cppFuncall(SEXP par, SEXP fn)
{
  SEXP R_fcall, ans;

  if(!isFunction(fn)) error("'fn' must be a function");
  R_fcall = PROTECT(lang2(fn, R_NilValue));

  SETCADR(R_fcall, par);
  ans=eval(R_fcall, R_GlobalEnv);
  UNPROTECT(1);
  return ans;
}

using namespace Rcpp;

// [[Rcpp::export]]
SEXP RcppFuncall(NumericVector par, Function fn)
{
  return fn(par);
}



/*** R
# R function to be called
fun <- function(x) {
  -cos(x[1])*cos(x[2])*exp(-((x[1] - pi)^2 + (x[2] - pi)^2))
}

# Input data
set.seed(3331)
x <- runif(1e3)

# Benchmarking
library(microbenchmark)
microbenchmark(
  cppFuncall(x, fun), RcppFuncall(x,fun), fun(x), times=1e4,
  unit="relative", control = list(warmup=100)
)
*/

-------- example_calling_r_functions.cpp ----

I've asked around about how to make things faster for function calls in
Rcpp but, from what I've been told it is difficult since the implementation
of Rcpp::Function actually has to go back to R to work (or something like
that :P). Now, this implementation, -cppFuncall-, has no problem when it
comes to passing wrong arguments, e.g. if you pass a character vector to it
R will complain but there won't be any system crash. One big difference is
that here I'm relying on passing all the function's arguments in a single
object while Rcpp::Function does not. Either way, if this is OK this could
be a nice extra feature for Rcpp, I'm thinking of optimization routines (or
other kinds of algorithms) that rely on calling R functions multiple times.

The thing is that I'm still learning C++  and  I'm not Rinternals expert at
all! So I would love to get some feedback from you guys. Does this
function, -cppFuncall-, looks OK? in other words, am I doing/getting
something wrong here?

Thanks,

George G. Vega Yon
+1 (626) 381 8171
http://www.its.caltech.edu/~gvegayon/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160803/d8814ddc/attachment.html>


More information about the Rcpp-devel mailing list