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