本机 R 函数的速度与 C++ 等效函数的速度

Speed of native R function vs C++ equivalent

当我将 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 功能设置得 方便 。只需要 two-liner。但它有一些 一些 开销是保存 random-number 生成器的状态,设置 try/catch 块用于异常处理等等。我们已经记录了如何跳过这些步骤中的 一些 ,但在许多情况下是 ill-advised.

简而言之,我认为您的比较选择不当:您进行基准测试的功能发生的事情太少了。还要注意单位:纳秒。你这里有很多测量错误。

但鼓舞士气的是,使用 'naive'(方便的)C++ 函数作为您编写的 one-liner,您将不会打败一些优化和调整 已经从 R 内部编译 代码。这实际上是一件好事,因为如果你这样做,你现在必须重写大块的 R。

编辑: 对于 kicks,这是第三个变体 'in the 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/Whosebug/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
>