解析プログラムを書いていて、逐次上から処理するようなことをやっていて、普通は計算結果を格納するオブジェクトを作っておいて、そこに計算結果を投げ込んでいけばそこそこに速い。
適当に、行列を作っておいて、行和をfor loop でゴリ押しすることを考える。
nr <- 300000 # 計算回数 nc <- 200 # 適当 mat <- matrix(runif(nr*nc), nr, nc) p <- numeric(nr) # 計算結果のオブジェクト for(i in seq(p)){ p[i] <- sum(mat[i,]) }
ここで、スクリプトを書いている最中に、オブジェクト定義してまた他に代入するのがなんかめんどくさくなったため、オブジェクトを作成するという手間を回避できないかと思って辿り着いたのが mapply.
mapply はあるベクトルに対して関数をそれぞれ当てはめていくイメージ。上のfor をmapply で書き直すとこんな感じ。
mapply(function(i) # for を宣言しているようなもの sum(mat[i,]) # やりたいこと , seq(p)) # i in seq(p) みたいなもの
とすれば、計算結果がいきなりベクトルで返ってくる。
これいけるじゃん! と思ったけど、計算速度的には遅いらしい。
system.time( for(i in seq(p)) p[i] <- sum(mat[i,]) )
ユーザ システム 経過 1.821 0.004 1.825
system.time( mapply(function(i) sum(mat[i,]), seq(p)) )
ユーザ システム 経過 1.977 0.008 1.984
おそらく最後にベクトル化するような作業で遅いんじゃないかと思っているが、最初にオブジェクトを定義しなくてもいいからメモリ的にいいんじゃない? とか思ったけどそのあたりは詳しくないから詳しい人教えてください。