我一直在开发一个使用Rcpp对大型医学图像文件组应用任意R代码的软件包。我注意到,我的Rcpp实现比原始的纯C版本慢得多。我发现区别在于通过Function调用函数,而不是原始的Rf_eval。我的问题是为什么性能降低了接近4倍,是否有方法可以加快函数调用以使其性能更接近于Rf_eval?
library(Rcpp)
library(inline)
library(microbenchmark)
cpp_fun1 <-
'
Rcpp::List lots_of_calls(Function fun, NumericVector vec){
Rcpp::List output(1000);
for(int i = 0; i < 1000; ++i){
output[i] = fun(NumericVector(vec));
}
return output;
}
'
cpp_fun2 <-
'
Rcpp::List lots_of_calls2(SEXP fun, SEXP env){
Rcpp::List output(1000);
for(int i = 0; i < 1000; ++i){
output[i] = Rf_eval(fun, env);
}
return output;
}
'
lots_of_calls <- cppFunction(cpp_fun1)
lots_of_calls2 <- cppFunction(cpp_fun2)
microbenchmark(lots_of_calls(mean, 1:1000),
lots_of_calls2(quote(mean(1:1000)), .GlobalEnv))
结果
Unit: milliseconds
expr min lq mean median uq max neval
lots_of_calls(mean, 1:1000) 38.23032 38.80177 40.84901 39.29197 41.62786 54.07380 100
lots_of_calls2(quote(mean(1:1000)), .GlobalEnv) 10.53133 10.71938 11.08735 10.83436 11.03759 18.08466 100
Rcpp::Function
从 C++ 调用 R 函数时,会带来相应的开销?你怎么能期望这比直接在 R 中运行更快呢? - Dirk EddelbuettelRf_eval()
适合您的需求,为什么不使用它呢?正如示例所示,Rcpp并不会阻止您这样做。 - Dirk EddelbuettelRf_eval()
是危险的,因为R错误(即Clongjmp
s)将绕过C ++对象的析构函数,从而导致内存泄漏/通常会引起未定义行为。Rcpp::Function
试图确保不会发生这种情况。 - Kevin Usheyinstall
到全局环境中。然后使用引用调用eval和全局环境。显然,我想要一种更清晰/更安全的方法,只是想减少性能损失。 - C. Hammill