C++
R
RDay 10

RとC++のドッキングで高速計算

More than 3 years have passed since last update.

ご存知の方が多いかとは思いますが、Rcppというパッケージを使用することで、Rの中でC++が使えます。
今回はざっとした使用方法と、ベンチマークを載せたいと思います。

用意するもの

  • R
  • RStudio(できれば)
  • コンパイラ(MacならXcodeなど)

使い方

1. Rcppパッケージをインストール

install.packages("Rcpp")

2. cppファイルを用意

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]

        .
        .
        .

// [[Rcpp::export]]を消すと動きません。

※) RStudioを使うと
"File" -> "New File" -> "C++ File"
で簡単にテンプレート作成できます。

3. Rで読み込む

例えばこんなcppファイルを

calculation.cpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]

int loop(int s, int t) {

  for(int i = 0; i < t; i++) {
    for(int j = 0 ; j < t; j++) {
      s++;
    }
  }

  return(s);
}

Rで読み込むのに必要な記述はこちら。

# パッケージの読み込み
library(Rcpp)

# cppファイルのコンパイル兼読み込み
sourceCpp("calculation.cpp")

※) rファイルとcppファイルが同階層の場合

あとはloopというC++の関数がR内で使えます。

ベンチマーク

環境

Mac OS X 10.10.4
プロセッサ: 3GHz Intel Core i7
メモリ: 8GB 1600 MHz DDR3

使用ソース

10000*10000回の単純計算を10セット繰り返し比較。

setwd("/Users/XXX/Desktop/R_programs/")
library(rbenchmark)
library(Rcpp)

# Rcppを使用した場合
with_rcpp <- function(n) {

  x <- 0

  sourceCpp("calculation.cpp")

  return( loop(x,n) )
}

# Rのみの場合
only_r <- function(n) {

  x <- 0

  for( i in 1:n ){
    for( j in 1:n ){
      x <- x + 1
    }
  }

  return(x)
}

loop_num <- 10000
benchmark( with_rcpp(loop_num), only_r(loop_num), replications = 10 )

結果

                 test replications elapsed relative user.self sys.self
2    only_r(loop_num)           10 233.215 8637.593   229.983    1.582
1 with_rcpp(loop_num)           10   0.027    1.000     0.024    0.003

relativeを見ると、なんと8000倍以上速くなっています。
まさに高速化。
sourceCpp()で一度コンパイルすると、2重にコンパイルしない仕組みになっているようです。

まとめ

高速化はもちろん、C++の標準ライブラリを使える利点もあります。
ただ、ベクターの書き方など、記述方法に少し癖のある感じなので下記を参照してください。
http://dirk.eddelbuettel.com/code/rcpp/Rcpp-attributes.pdf

一番詳しいドキュメントはこちら
https://cran.r-project.org/web/packages/Rcpp/Rcpp.pdf

Rの統計関数とかプロットとか便利だけど、一部計算をカスタマイズして高速化とかしたい!と思ってる方、是非使ってみてください。