関数の時間計測

さて、前回C拡張を利用すればRが爆速化するというネタを書きました。前回のエントリでは実際どれくらい早くなったかが示せていなかったので、示そうと思ったのですが、よく考えたら、そもそもRで時間の計測の仕方がよく分かっていないという事実に気づいたため、勉強しました。非常に簡単です。

Rでの時間計測方法

system.time()に関数を渡す。以上です。非常に簡単ですね。
Rの関数定義の基本/関数の実行速度の計測 - RjpWiki
を見ればすぐ分かりますが、色々な時間が返ってきます。

というわけで早速試す

さしてうまい例が思いつかなかったので、一様分布の乱数を求めるという至って意味の無い関数を用意してみます。
関数runifというものを利用していますが、これは一様分布から得られる乱数を引数の数だけ返すというものです。
for分と併用して、runifを呼び出す回数と、runifに渡す引数を与える関数を定義してやりました。

record <- function(n,m) {
  for (i in 1:n) {
    runif(m)
  }
}

system.time(record(1000,1))
system.time(record(1,1000))
system.time(record(1000,1000))
system.time(record(100000,100000))

実行結果

> system.time(record(1000,1))
   ユーザ   システム       経過  
     0.008      0.000      0.009 
> system.time(record(1,1000))
   ユーザ   システム       経過  
         0          0          0 
> system.time(record(1000,1000))
   ユーザ   システム       経過  
     0.057      0.000      0.058 
> system.time(record(100000,100000))
   ユーザ   システム       経過  
   546.050     75.077    629.399 

始めの2つの結果から、forをまわす回数の影響が、runifに渡す引数と比べて非常に大きいことが分かりますね。同じ「一様分布から乱数を1000個発生させる」目的なら、forを使う方が断然遅いことが分かります。(1000回程度では体感できるほどではなさそうですが…)
ついでに、最後の例は桁数を一つ間違ってしまい、プログラムが全然止まらなくなり悲しい気持ちになりました。Rにおいては全く持ってforはおぞましい。