意外に速いRタソ compared to C++

ちょいとRcppをがっつり使ってみようと、その試行錯誤記録が続く予定。
速度検証のテストコードとして、ランダムウォークする系列データを生成するコードを書いた。

library(Rcpp)
sourceCpp(code='
  #include<vector>
  #include <functional>
  #include <numeric>
  #include <Rcpp.h>

  using namespace Rcpp;
  // [[Rcpp::export]]
  NumericVector randomWalk(int size)
  {
    RNGScope scope;
    NumericVector rand(Rcpp::rnorm(size));
    NumericVector cum(Rcpp::rnorm(size));
    std::partial_sum(rand.begin(), rand.end(), cum.begin(), std::plus<double>());
    return cum;
  }
')

これをピュアにRで書くと

cumsum(rnorm(10^5))

とだけ書けばよい。ちなみに、この2つは同じ結果をちゃんと返す。

> set.seed(100)
> randomWalk(10)
 [1] -0.5021924 -0.3706612 -0.4495783  0.4372065  0.5541778  0.8728079  0.2910172  1.0055499  0.1802905
[10] -0.1795716
> set.seed(100)
> cumsum(rnorm(10))
 [1] -0.5021924 -0.3706612 -0.4495783  0.4372065  0.5541778  0.8728079  0.2910172  1.0055499  0.1802905
[10] -0.1795716

計算速度の比較をすると・・・

#結果比較
> library(rbenchmark)
> res <- benchmark(randomWalk(10^5), cumsum(rnorm(10^5)), order="relative")
> res[,1:4]
                 test replications elapsed relative
2 cumsum(rnorm(10^5))          100    1.49    1.000
1    randomWalk(10^5)          100    2.63    1.765

あらら、Rの方が速いよと、1.77倍速いよと。これはRの例の方が、直にCで書かれた部分だけ呼んでるからだろうと推測。
もうちょいいらんメモリ消費を削って、Rcpp版を書きなおして速くすると・・・以下のような感じ。

library(Rcpp)
sourceCpp(code='
  #include<vector>
  #include <functional>
  #include <numeric>
  #include <Rcpp.h>

  using namespace Rcpp;
  // [[Rcpp::export]]
  NumericVector randomWalk(int size)
  {
    RNGScope scope;
    NumericVector rand(Rcpp::rnorm(size));
    std::partial_sum(rand.begin(), rand.end(), rand.begin(), std::plus<double>());
    return rand;
  }
')

で、結果を比べると10%程度Rcpp版の方が速いというレベルか。

> res <- benchmark(randomWalk(10^5), cumsum(rnorm(10^5)), order="relative")
> res[,1:4]
                 test replications elapsed relative
1    randomWalk(10^5)          100    1.32    1.000
2 cumsum(rnorm(10^5))          100    1.49    1.129