本地R函数与c++等效函数的速度



当我比较R中本地Gamma函数gamma与c++等效std::tgamma的速度时,我发现后者大约慢10-15倍。为什么?我知道会有一些不同,但这很重要,不是吗?

我实现:

library("Rcpp")
library("microbenchmark")
cppFunction("
double gammacpp(double x) {
return(std::tgamma(x));
}
")
x = max(0, rnorm(1, 50, 25))
microbenchmark(gamma(x), gammacpp(x))

结果在我的机器上:

Unit: nanoseconds
expr         min   lq    mean median uq  max neval cld
gamma(x)    100   101  124.91  101  102 1001   100   a
gammacpp(x) 1000 1101 1302.98 1200 1300 9401   100   b

gamma()的代码(例如输入gamma<Return>):它只是调用一个原语。

您的Rcpp函数设置为方便。只需要两句话。但是它有一些开销,比如保存随机数生成器的状态,设置try/catch块进行异常处理等等。我们已经记录了如何跳过这些步骤中的一些,但在许多情况下,这是不明智的。

简而言之,我的观点是你选择了一个糟糕的比较:在你基准测试的函数中发生的事情太少了。还要注意单位:纳秒。你这里有很多测量误差。

但是鼓舞人心的是,用一个"幼稚的"(和方便的)c++函数作为你写的一行代码,你不会打败一些优化和调优的,并且已经从R中编译了代码。这实际上是一件好事,因为如果你这样做,你现在将不得不重写大量的R。

Edit:For kicks,这里是第三个变体'in middle',我们使用Rcpp调用r的相同C API。

#include <Rcpp.h>
// [[Rcpp::export]]
double gammaStd(double x) { return (std::tgamma(x)); }
// [[Rcpp::export]]
Rcpp::NumericVector gamma_R(Rcpp::NumericVector x) { return (Rcpp::gamma(x)); }
/*** R
set.seed(123)
x <- max(0, rnorm(1, 50, 25))
res <- microbenchmark::microbenchmark(R = gamma(x), Cpp = gammaStd(x), Sugar = gamma_R(x) )
res
*/

> Rcpp::sourceCpp("~/git/stackoverflow/72383007/answer.cpp")
> set.seed(123)
> x <- max(0, rnorm(1, 50, 25))
> res <- microbenchmark::microbenchmark(R = gamma(x), Cpp = gammaStd(x), Sugar = gamma_R(x) )
> 
res
Unit: nanoseconds
expr  min     lq     mean median     uq     max neval cld
R  102  112.0   136.95    124  134.5    1068   100   a
Cpp 1111 1155.5 11930.02   1186 1260.0 1054813   100   a
Sugar 1142 1201.0  6355.92   1246 1301.5  506628   100   a
> 

最新更新