compilerパッケージ使ってバイトコンパイルすればRでも十分イケる計算速度がでるんじゃないか?
最近発刊されたR言語使い必携の書
をパラパラ読んでいるのですが、そこにcompilerパッケージ*1の使い方も書いてあって、これを見た限りcompilerパッケージを使ってコンパイルした関数はコンパイルしてないそのままの関数よりも10倍程度速くなってるっぽいので、やってみようと。そしてRでも速度的にやっていけるのかを見極めたい。
金融系での応用を念頭に、サンプルに使用する関数は以前書いたブラウン運動のパスを生成する関数とした。
4行で書くブラウン運動のパス - My Life as a Mock Quant
まずはパッケージの読み込み&関数の生成をして・・・
library(compiler) #ブラウン運動のパスを返す関数 BrownianPath <- function(number.of.path, number.of.time) { apply(matrix(rnorm(number.of.path * number.of.time), nrow = number.of.time, ncol = number.of.path), 2, cumsum) }
ここで作った関数をcmpfun関数でコンパイルする
BrownianPath.compiled <- cmpfun(BrownianPath)
そして各々実行してその計算時間を測定してやると・・・
> N <- 10^4 > T <- 10^3 > system.time(BrownianPath(N, T)) ユーザ システム 経過 4.44 0.11 4.57 > system.time(BrownianPath.compiled(N, T)) ユーザ システム 経過 4.40 0.10 4.61
ほぉーら高速化できて・・・ないですね、はい。
次に書籍にある例(自作のsum関数)で試してみる。まずは関数を定義&コンパイル
mysum <- function(x) { s <- 0 for(y in x){ s <- s + y } s } mysum.compiled <- cmpfun(mysum)
これを実行して速度比較を実施
> N <- 10^6 > system.time(mysum(1:N)) ユーザ システム 経過 1.86 0.00 1.86 > system.time(mysum.compiled(1:N)) ユーザ システム 経過 0.31 0.00 0.31
たしかに6倍程度には速くなった。コンパイルする関数に強く依存するということか。
〜2012/2/1追記〜
@teramonagi cmpfun は for とかベタ書きした方が最適化されるみたいですね。ベクトル化とか apply 系にはあまり効果がないみたいです。 URL
2012-02-01 00:15:34 via web to @teramonagi
だそうです。@kos59125氏毎度のアドバイスありがとうございます!
〜2013/11/13追記〜
こちらを参照すると
- 「Tierny氏の compiler パッケージが推奨パッケージになった」http://www.okada.jp.org/RWiki/?R%20%A5%D0%A1%BC%A5%B8%A5%E7%A5%F33%A4%CB%B4%F3%A4%BB%A4%C6#o251b85f
現在のR(及びほとんどの貢献パッケージ)の内部関数を利用する関数以外は予めバイトコンパイルされているか,読み込み時にバイトコンパイルされるようです.
だそうなので、直接自分たちでコンパイルする必要はないかも。
*1:R-2.13以降に標準装備っぽい