Rcppを使用して、大規模な医療画像ファイルのグループに任意のRコードを適用するパッケージを作成しています。自分のRcppの実装が元の純粋なCバージョンよりもかなり遅いことに気付きました。 Functionを介して関数を呼び出すこととの違いを、元のRf_evalと比較して追跡しました。私の質問は、4倍のパフォーマンス低下に近づくのはなぜですか、そしてRf_evalに近いパフォーマンスを得るために関数呼び出しを高速化する方法がありますか?Rcpp関数がRf_evalより遅い
例:それは物事がプログラマにばかばかしいほどクリーンが見えますので
library(Rcpp)
library(inline)
library(microbenchmark)
cpp_fun1 <-
'
Rcpp::List lots_of_calls(Function fun, NumericVector vec){
Rcpp::List output(1000);
for(int i = 0; i < 1000; ++i){
output[i] = fun(NumericVector(vec));
}
return output;
}
'
cpp_fun2 <-
'
Rcpp::List lots_of_calls2(SEXP fun, SEXP env){
Rcpp::List output(1000);
for(int i = 0; i < 1000; ++i){
output[i] = Rf_eval(fun, env);
}
return output;
}
'
lots_of_calls <- cppFunction(cpp_fun1)
lots_of_calls2 <- cppFunction(cpp_fun2)
microbenchmark(lots_of_calls(mean, 1:1000),
lots_of_calls2(quote(mean(1:1000)), .GlobalEnv))
結果
Unit: milliseconds
expr min lq mean median uq max neval
lots_of_calls(mean, 1:1000) 38.23032 38.80177 40.84901 39.29197 41.62786 54.07380 100
lots_of_calls2(quote(mean(1:1000)), .GlobalEnv) 10.53133 10.71938 11.08735 10.83436 11.03759 18.08466 100
はあなたがCからR関数を呼び出す_areことを知っ++ _すべて見合っオーバーヘッドを含むていますか?これがちょうどRより速いとはどういうことが期待できますか? –
また、 'Rf_eval()'があなたのニーズに合っていると思うなら、それを使わないのはなぜですか?例で示すように、Rcppはあなたがそうするのを妨げません。 –
また、C++コンテキストから直接 'Rf_eval()'を呼び出すことは、Rエラー(C 'longjmp's)がC++オブジェクトのデストラクタをバイパスし、メモリがリークする/一般的に未定義の動作を引き起こすので危険です。 'Rcpp :: Function'はそれが起こらないことを確認しようとします。 –