R で関数の実行時間を測定する system.time は、
system.time(rnorm(10000000))
のように使う。
「ふつう」のプログラミング言語の感覚だと、rnorm が評価されてから system.time が呼び出されるはず。経過時間を測ろうと思ったら、rnorm を評価する前に現在時刻を記録しておかないとダメなのに、どうなっているんだろう?
早速、system.time のコードを読んでみた。R ソースコードより引用。
function (expr, gcFirst = TRUE) { ppt <- function(y) { if (!is.na(y[4L])) y[1L] <- y[1L] + y[4L] if (!is.na(y[5L])) y[2L] <- y[2L] + y[5L] y[1L:3L] } if (!exists("proc.time")) return(rep(NA_real_, 5L)) if (gcFirst) gc(FALSE) time <- proc.time() on.exit(cat("Timing stopped at:", ppt(proc.time() - time), "\n")) expr new.time <- proc.time() on.exit() structure(new.time - time, class = "proc_time") }
普通に expr を呼んでるだけ! このことから、R は引数を遅延評価するという驚愕の事実が分かった。検索すると、Rにおける遅延評価とスコープ - もうカツ丼はいいよな にまとめが見つかった。
竹内関数 - Wikipedia (たらい回し関数) も試してみたが、たしかに速い。