始める無料で始める

STL のベクター

standard template library(stl)は、柔軟なアルゴリズムとデータ構造を含む C++ のライブラリです。たとえば、stl の double ベクターは、Rcpp の NumericVector に相当する「ネイティブ C++」の型です。次のコードは、10 要素の標準的な double ベクター x を作成します。

std::vector<double> x(10);

通常は、mean()round()abs() など R と同様に使える便利なメソッドにアクセスできるため、Rcpp のベクター型を使うほうが理にかなっています。しかし、stl のベクターには、毎回データをコピーすることなく動的にサイズを変更できるという利点があります。これにより、前の演習で扱った「bad」関数のような、よりシンプルなコードを書きつつ、「good」コードに匹敵する性能を維持できます。

この演習はコースの一部です

Rcpp で R コードを最適化する

コースを見る

演習の手順

  • 正の数を選び出す、stl ベクター版の関数 select_positive_values_std() の定義を完成させてください。
    • 関数の戻り値の型を、std::vector<double> を用いた標準の double ベクターに設定します。
    • サイズが 0 の標準 double ベクター positive_x を定義します。
    • for ループ内の if ブロックで、positive_xpush_back() を使って、x の i 番目の要素を追加します。
  • 比較用に、前の演習の good_select_positive_values_cpp() がワークスペースに用意されています。コンソール出力を確認して、2 つの関数の相対的な速度を見てみましょう。

実践的なインタラクティブ演習

このサンプルコードを完成させて、この演習に挑戦してみましょう。

#include 
using namespace Rcpp;

// Set the return type to a standard double vector
// [[Rcpp::export]]
___ select_positive_values_std(NumericVector x) {
  int n = x.size();
  
  // Create positive_x, a standard double vector
  ___;
    
  for(int i = 0; i < n; i++) {
    if(x[i] > 0) {
      // Append the ith element of x to positive_x
      ___;
    }
  }
  return positive_x;
}

/*** R
set.seed(42)
x <- rnorm(1e6)
# Does it give the same answer as R?
all.equal(select_positive_values_std(x), x[x > 0])
# Which is faster?
microbenchmark(
  good_cpp = good_select_positive_values_cpp(x),
  std = select_positive_values_std(x)
)
*/
コードを編集して実行