裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

ダメ出し:apply関数は遅かった・・・

2011年12月02日 | ブログラミング

apply関数は遅かった・・・


確かに apply は遅い。その代わりに colMeans, rowSums  を使って定義通りに書くと,ヘタに行列演算するより速い。
colMeans, rowSums を使って書いたものと,結果の格納領域を事前に確保して行列演算をするのは,ほとんど同じくらいの速度である。
それでもまあ,実行時間は1秒ミマンなのだから,こんな細かいことを言っても,毒にも薬にもならぬ。

> # apply
> Rprof()
> varA <- apply(d, 2, var)
> Rprof(NULL)
> print(a <- summaryRprof()$sampling.time)
[1] 3.56

> # colMeans, rowSums
> Rprof()
> means <- colMeans(d)
> varA2 <- rowSums((t(d)-means)^2)/(n-1)
> Rprof(NULL)
> print(a2 <- summaryRprof()$sampling.time)
[1] 0.1
> all.equal(varA, varA2)   # 結果が一致していることを確認
[1] TRUE

行列演算を使うと速いけど,cbind(  ) を使って結果をつなげてゆくなんてことをすると,遅くなってしまう。

> # matrix operation (2)
> Rprof()
> varC <- NULL
> for(i in 1:1000) {
+ varC <- cbind(   # cbind でつなぐのは悪手
+   varC,
+   (rep(1, n) %*% d[,((i-1)*100+1):((i)*100)]^2 -
+   (rep(1, n) %*% d[,((i-1)*100+1):((i)*100)])^2 / n)
+   / (n - 1)
+ )}
> varC <- as.numeric(varC)
> Rprof(NULL)
> print(c <- summaryRprof()$sampling.time)
[1] 0.96
>
> # matrix operation (2-2)
> Rprof()
> varC2 <- matrix(0, 100, 1000)  # 前もって必要なだけ領域を確保しておく
> for(i in 1:1000) {
+   varC2[,i] <- (rep(1, n) %*% d[,((i-1)*100+1):((i)*100)]^2 -
+     (rep(1, n) %*% d[,((i-1)*100+1):((i)*100)])^2 / n)/ (n - 1)
+ }
> varC2 <- as.vector(varC2)
> Rprof(NULL)
> print(c2 <- summaryRprof()$sampling.time)
[1] 0.08
> all.equal(varC, varC2)   # 結果が一致していることを確認
[1] TRUE

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村