如果您真的想获得性能改进,则必须编写代码以利用底层硬件并发性。你可以使用这个RcppParallel
包来做到这一点,它parallelFor
是一个理想的容器。
您还可以尝试更现代的R/C++
. Rcpp11
几天后发布的下一个版本将具有自动线程化的糖,使expSugar
之前的答案更好。
考虑:
#include <Rcpp.h>
using namespace Rcpp ;
// [[Rcpp::export]]
NumericVector exp2(NumericVector x) {
NumericVector z = Rcpp::clone(x);
int n = z.size();
for (int i=0; i<n; ++i)
z[i] = exp(z[i]);
return z;
}
// [[Rcpp::export]]
NumericVector expSugar(NumericVector x) {
return exp(x) ;
}
/*** R
library(microbenchmark)
x <- rcauchy(1000000)
microbenchmark(exp(x), exp2(x), expSugar(x))
*/
我得到Rcpp
:
$ RcppScript /tmp/exp.cpp
> library(microbenchmark)
> x <- rcauchy(1e+06)
> microbenchmark(exp(x), exp2(x), expSugar(x))
Unit: milliseconds
expr min lq median uq max neval
exp(x) 7.027006 7.222141 7.421041 8.631589 21.78305 100
exp2(x) 6.631870 6.790418 7.064199 8.145561 31.68552 100
expSugar(x) 6.491868 6.761909 6.888111 8.154433 27.36302 100
非常好,但有点轶事的改进,可以通过各种内联等来解释......如其他答案和评论中所述。
使用Rcpp11
自动螺纹糖,我得到:
$ Rcpp11Script /tmp/exp.cpp
> library(microbenchmark)
> x <- rcauchy(1e+06)
> microbenchmark(exp(x), exp2(x), expSugar(x))
Unit: milliseconds
expr min lq median uq max neval
exp(x) 7.029882 7.077804 7.336214 7.656472 15.38953 100
exp2(x) 6.636234 6.748058 6.917803 7.017314 12.09187 100
expSugar(x) 1.652322 1.780998 1.962946 2.261093 12.91682 100