我正在编写一个函数,其中在最深层运行二进制操作。用Rcpp编写此函数使我对固定的二进制操作(例如+
)有巨大的性能改进,但是当我试图找到将其归纳为用户输入函数的方法时,我会损失很多性能。这是一个示例:
首先,我将在R和Rcpp中定义相同的simple
二进制操作:
library(Rcpp)
library(benchmark)
cppFunction(
code = "double simple_cpp(double a, double b) {
double out = cos(a) + sin(b);
return(out);
}")
simple_r <- function(a,b) cos(a) + sin(b)
然后,将函数作为参数并多次执行此操作的函数
cppFunction(
code = "NumericVector many_simple_cpp(NumericVector a, NumericVector b, Function simple) {
NumericVector out(a.size());
for(int i = 0; i<a.size(); i++){
out[i] = Rcpp::as<double>(simple(a[i],b[i]));
}
return(out);
}")
第三,使用预定义的C ++函数作为运算符的函数
cppFunction(
code = "
double operation(double a, double b){
return(cos(a) + sin(b));
}
NumericVector full_native_cpp(NumericVector a, NumericVector b) {
NumericVector out(a.size());
for(int i = 0; i<a.size(); i++){
out[i] = operation(a[i],b[i]);
}
return(out);
}")
一些性能指标:
test <- 1:10000
benchmark(rfun = many_simple_cpp(test,test,simple_r),
cppfun = many_simple_cpp(test,test,simple_cpp),
cppnative = full_native_cpp(test,test))
test replications elapsed relative user.self sys.self
2 cppfun 100 15.95 159.5 15.93 0.02
3 cppnative 100 0.10 1.0 0.09 0.00
1 rfun 100 14.71 147.1 14.67 0.00
我的问题是:第三个示例清楚地表明,我可以在不损失过多性能的情况下概括操作的类型,但是我的两种方法都不正确。我认为性能下降是由于多次调用Rcpp::as<double>(simple(a[i],b[i]));
引起的。有没有办法让用户创建C ++函数作为参数传递(或将R函数转换为C ++)?
为什么通过simple_cpp
和simple_r
给我类似的结果?我希望使用simple_cpp
进行调用会具有更好的性能,因为它是Rcpp定义的函数。