分からんこと多すぎ

何故か就職できたので技術磨く。一人前の多重線形代数使いを目指しつつ、機械学習、データマイニングをやる

R言語のdo.callとReduceの速度を比較する

概要


行列のリストをbindして、巨大な一つの行列にすることを考える。
Rjpwiki的には、do.callでbindするらしいが、実際のところ、do.callとReduceとdoMCのどれが一番速いのか気になったので、比較してみた。

実験条件


適当な100*100の行列を100個用意して、リストに格納する。
それをbindする時間で競う。

mat.list <- list(NULL)

for(i in 1:100){
  mat.list[[i]] <- matrix(runif(100*100),nrow=100,ncol=100)
}

結果


bindに使う場合、Reduceは異様なほど遅い。
do.callとdoMCはタスクと環境次第。

ちなみにbind系なら、rbind.fill(plyrパッケージ)が最強らしい。
The rbinding race: for vs. do.call vs. rbind.fill | (R news & tutorials)

> system.time( tmp <- do.call(args=mat.list,what=cbind))
   user  system elapsed 
  0.005   0.006   0.012 
> system.time( tmp <- Reduce(x=mat.list,f=cbind))
   user  system elapsed 
  0.242   0.253   0.495 
library('doMC')
registerDoMC(1)

> system.time( tmp <- foreach(i = 1:100,.combine=cbind) %dopar% { mat.list[[i]]  } )
   user  system elapsed 
  0.055   0.005   0.059 

ただ、Reduce本来の使い方(演算)をするならReduceの方が速いらしい。
過去の配列を保持し続けるようなことが不向きらしい?

> system.time( tmp <- do.call(args=mat.list,what=sum))
   user  system elapsed 
  0.010   0.001   0.010

> system.time( tmp <- Reduce(x=mat.list,f=sum))
   user  system elapsed 
  0.001   0.000   0.002
    • 追記

R help - What is the difference between Reduce(…) and do.call(…) ?

こういうことらしい。

Reduceはforの延長上にあって、do.callは関数を引数全体に一括でかける感じ。

まあ要するに、大体do.callで良いという話。