用于算术运算的c ++性能不佳

Ale*_*lex 0 performance r rcpp

我只使用R和c ++中的算术运算(使用rcpp)编写了一个非常简单的函数.比较这两个函数显示我的c ++实现比我的R代码慢,这让我很困惑.

c ++版本:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector dn_cpp(NumericVector x, NumericVector sigma, NumericVector mu) {
  return   1/(sqrt(2*M_PI)*sigma) * exp(pow((x-mu),2)/(-2*pow(sigma, 2)) );
}
Run Code Online (Sandbox Code Playgroud)

R版:

dn_r <- function(x, sigma, mu) {
  1/(sqrt(2*pi)*sigma) * exp((x-mu)^2/(-2*sigma^2)  )
}
Run Code Online (Sandbox Code Playgroud)

比较两者:

library(microbenchmark)
microbenchmark(
  dn_r(1,1,1),
  dn_cpp(1,1,1),
  times = 10000
)

# Unit: nanoseconds
#             expr  min   lq      mean median     uq     max neval
#    dn_r(1, 1, 1)  509  567  667.1547    627  715.5   12690 10000
#  dn_cpp(1, 1, 1) 1094 1242 1713.8351   1335 1479.0 3192711 10000
Run Code Online (Sandbox Code Playgroud)

谁能解释为什么我的c ++函数缺乏性能?

duc*_*ayr 6

像往常一样,李哲源Dirk Eddelbuettel是完全正确的; 对于这些类型的操作,绝对没有理由期望C++版本比您调用函数的数据的R版本更快.我添加这个答案只是为了证明李哲源的建议:

microbenchmark(
    dn_r(1,1,1),
    dn_cpp(1,1,1),
    times = 10000
)

Unit: microseconds
            expr   min    lq      mean median    uq       max neval
   dn_r(1, 1, 1) 4.061 4.390  7.569112  4.869 5.175 26308.271 10000
 dn_cpp(1, 1, 1) 8.362 9.025 12.148559  9.265 9.653  5834.242 10000

microbenchmark(
    dn_r(rnorm(1e3), 1, 1),
    dn_cpp(rnorm(1e3), 1, 1),
    times = 10000
) 

Unit: microseconds
                      expr     min      lq     mean  median       uq      max
   dn_r(rnorm(1000), 1, 1) 298.134 303.631 313.9681 305.453 308.7080 4111.497
 dn_cpp(rnorm(1000), 1, 1) 199.949 205.571 214.6522 207.414 210.5015 3859.939

microbenchmark(
    dn_r(rnorm(1e5), 1, 1),
    dn_cpp(rnorm(1e5), 1, 1),
    times = 10000
) 

Unit: milliseconds
                       expr      min       lq     mean   median       uq      max
   dn_r(rnorm(1e+05), 1, 1) 28.60395 29.28238 30.85371 29.46879 29.95939 160.0769
 dn_cpp(rnorm(1e+05), 1, 1) 18.89528 19.44148 20.10618 19.60433 19.75410 143.7250
Run Code Online (Sandbox Code Playgroud)

使用短向量,额外的开销意味着R版本将更快,而您可以通过更长的向量获得一些性能增益.