web-dev-qa-db-ja.com

std :: vectorよりもRcpp :: NumericVectorを優先する必要がありますか?

Rcpp::NumericVectorよりもstd::vector<double>を好む理由はありますか?

たとえば、以下の2つの関数

// [[Rcpp::export]]
Rcpp::NumericVector foo(const Rcpp::NumericVector& x) {
  Rcpp::NumericVector tmp(x.length());
  for (int i = 0; i < x.length(); i++)
    tmp[i] = x[i] + 1.0;
  return tmp;
}

// [[Rcpp::export]]
std::vector<double> bar(const std::vector<double>& x) {
  std::vector<double> tmp(x.size());
  for (int i = 0; i < x.size(); i++)
    tmp[i] = x[i] + 1.0;
  return tmp;
}

それらの動作パフォーマンスとベンチマークパフォーマンスを考慮すると同等です。 Rcppがシュガーとベクトル化された操作を提供することは理解していますが、Rのベクトルを入力として受け取り、ベクトルを出力として返すだけの場合、どちらを使用するかに違いはありますか? std::vector<double>を使用すると、Rと対話するときに問題が発生する可能性がありますか?

13
Tim

「わからない場合は、時間を計ってください。」

必要なのは、すでに持っているファイルに次の数行を追加することだけです。

_/*** R
library(microbenchmark)
x <- 1.0* 1:1e7   # make sure it is numeric
microbenchmark(foo(x), bar(x), times=100L)
*/
_

次に、sourceCpp("...yourfile...")を呼び出すだけで、次の結果が生成されます(さらに、符号付き/符号なしの比較に関する警告)。

_R> library(microbenchmark)

R> x <- 1.0* 1:1e7   # make sure it is numeric

R> microbenchmark(foo(x), bar(x), times=100L)
Unit: milliseconds
   expr     min      lq    mean  median      uq      max neval cld
 foo(x) 31.6496 31.7396 32.3967 31.7806 31.9186  54.3499   100  a 
 bar(x) 50.9229 51.0602 53.5471 51.1811 51.5200 147.4450   100   b
R> 
_

bar()ソリューションは、Rメモリプールに[〜#〜] r [〜#〜]オブジェクトを作成するためにコピーを作成する必要があります。 foo()はしません。それは大きいあなたが走るベクトル何度もにとって重要です。ここでは、約1.8のクローズの比率が見られます。

実際には、あるコーディングスタイルを他のコーディングスタイルよりも優先するかどうかは問題ではないかもしれません。

14