本当にパフォーマンスを向上させたい場合は、基盤となるハードウェアの同時実行性を活用するコードを作成する必要があります。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