Hi Jiefei, Calling into R from C++ code is more complicated than one might think. Please see Tomas Kalibera's post here: https://developer.r-project.org/Blog/public/2019/03/28/use-of-c---in-packages/index.html
The Rcpp Function class is more expensive than a regular Rf_eval() because it tries to prevent errors (longjmps) from jumping to the top level, so that the C++ stack can be properly unwound. In addition, your example also pays a cost for the indirect function calls used with Rcpp attributes, since the generated R wrapper functions will then use `.Call()` under the hood. You could also try to directly use .Call() to avoid that extra R function call overhead. Even then, R's dispatch system for primitive functions (like `^`) is likely still going to be faster than what you get from the .Call() interface, especially since some extra validation does occur when using .Call(). In practice, that difference is usually negligible outside of synthetic benchmarks. Best, Kevin On Tue, Jun 18, 2019 at 10:41 AM King Jiefei <szwj...@gmail.com> wrote: > > Hi, > > I'm looking for a most efficient way to call an R function from C++ in a > package. I know there are two functions (`R_forceAndCall` and `Rf_eval`) > that can do the "call" part, but both are slow compared to calling the same > function in R. I also try to use Rcpp and it is the worse one. Here is my > test code: > > C++ code: > ``` > // [[Rcpp::export]] > SEXP C_test1(SEXP f, SEXP x) { > SEXP call =PROTECT(Rf_lang2(f, x)); > SEXP val = R_forceAndCall(call, 1, R_GlobalEnv); > UNPROTECT(1); > return val; > } > > // [[Rcpp::export]] > SEXP C_test2(SEXP expr, SEXP env) { > SEXP val = Rf_eval(expr, env); > return val; > } > > // [[Rcpp::export]] > SEXP C_test3(SEXP f,SEXP x) { > Function fun(f); > return fun(x); > } > ``` > > R code: > ``` > testFunc<-function(x){ > x=x^2 > return(x) > } > evn=new.env() > evn$x=x > expr=quote(testFunc(evn$x)) > > testFunc(evn$x) > C_test1(testFunc, evn$x) > C_test2(expr,evn) > C_test3(testFunc,evn$x) > ``` > > For the results, I run each function 1,000,000 times: > > - testFunc : 0.47 sec > - C_test1 : 2.46 sec > - C_test2 : 2.74 sec > - C_test3 : 18.86 sec > > It is clear to see that calling an R function in R is the fast one, it is > about 5X faster than ` R_forceAndCall ` and ` Rf_eval`. the latter two > functions have a similar performance and using Rcpp is the worst one. Is it > expected? Why is calling an R function from C++ much slower than calling > the function from R? Is there any faster way to do the function call in C++? > > Best, > Jiefei > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel