各所で行方向の和を求める際にはapplyよりもrowSumsがオススメであるということを聞いた。本当にそうなのか、確認するためにコードを書いてみた。下記の2パターンでapplyとrowSumsの実行時間がどのように変化するかということを調べている。サイズによる処理時間の変化を観察することにする。
- 列数10で固定で、行数のみ増やす
- 行数10で固定で、列数のみ増やす
# 行方向のみ数が変化する(列数は10で固定) for( sz in (1:10)*50000 ){ data <- matrix(runif(sz*10),nrow=sz) print(system.time(rowSums(data))) # print(system.time(apply(data,1,sum))) # applyの実行時間を測る場合はコメントを解除 }
# 列方向のみ数が変化する(行数は10で固定) for( sz in (1:10)*50000 ){ data <- matrix(runif(sz*10),ncol=sz) print(system.time(rowSums(data))) # print(system.time(apply(data,1,sum))) }
上のような時間を出力するコードを私のマシンで実行し、出力された経過時間(system.time関数の返り値の第3引数)をプロットしたのが下の二つの図である。上図は列数固定の結果である。横軸は行数で縦軸は経過時間(単位は秒)を表している。下図は行数固定とした結果である。横軸は列数で、縦軸は経過時間(単位は秒)を表している。経過時間は、表示など処理のすべてにかかった時間である。下図は時間が0になっているが、表示の都合上小数点2桁までしか表されず、それ以下の細かい値まで取れていないためである。各計測点で2回経過時間を計測した平均をとっているが、2回の測定とも、概ね同じような実行時間になっていた。この結果より次のことが言える。
- applyは行数に比例して処理時間がかかるのに対し、rowSumsは数十万行の規模でもほぼ一定の短い時間で処理が可能
- 行数が一定の場合でもrowSumsの性能がapplyを上回るものの、その差は列数固定の場合よりは小さい
なお、rowSumsの仲間で、列方向の和を求める関数colSumsが存在する。また、マトリックスの行/列方向の平均を求める関数として、rowMeans/colMeansというものが存在する。今回のような単純な集計に対しては、applyよりも更に速い処理ができる関数があるということは覚えておいて損はないと思う。
0 件のコメント:
コメントを投稿