Rでのプロファイリング

Rには、パフォーマンスとメモリをプロファイリングするための組み込みユーティリティ-Rprofがあります。 コンソールで?Rprof



して、詳細を確認します。



プロファイラーは次のように機能します。

  1. Rprofを呼び出し、プロファイリングデータが保存されるファイルの名前を渡すことにより、プロファイラーを起動します。
  2. 解析したいR関数を呼び出します
  3. Rprof(NULL)



    を呼び出して、プロファイラーを停止しRprof(NULL)



  4. Rprofによって作成されたファイルを分析します。通常はsummaryRprof







例:

 Rprof(tmp <- tempfile()) example(glm) Rprof() summaryRprof(tmp) unlink(tmp)
      
      





結果は次のようになります。

 $by.self self.time self.pct total.time total.pct "str.default" 0.02 14.29 0.10 71.43 "deparse" 0.02 14.29 0.04 28.57 "as.name" 0.02 14.29 0.02 14.29 "formals" 0.02 14.29 0.02 14.29 "make.names" 0.02 14.29 0.02 14.29 "parent.frame" 0.02 14.29 0.02 14.29 "pmatch" 0.02 14.29 0.02 14.29 $by.total total.time total.pct self.time self.pct "eval" 0.14 100.00 0.00 0.00 "withVisible" 0.14 100.00 0.00 0.00 "str.default" 0.10 71.43 0.02 14.29 "<Anonymous>" 0.10 71.43 0.00 0.00 "capture.output" 0.10 71.43 0.00 0.00 "doTryCatch" 0.10 71.43 0.00 0.00 "evalVis" 0.10 71.43 0.00 0.00 ".rs.valueContents" 0.10 71.43 0.00 0.00 ".rs.valueFromStr" 0.10 71.43 0.00 0.00 "str" 0.10 71.43 0.00 0.00 "try" 0.10 71.43 0.00 0.00 "tryCatch" 0.10 71.43 0.00 0.00 "tryCatchList" 0.10 71.43 0.00 0.00 "tryCatchOne" 0.10 71.43 0.00 0.00 "do.call" 0.08 57.14 0.00 0.00 "strSub" 0.08 57.14 0.00 0.00 "deparse" 0.04 28.57 0.02 14.29 "example" 0.04 28.57 0.00 0.00 "FUN" 0.04 28.57 0.00 0.00 "lapply" 0.04 28.57 0.00 0.00 "match" 0.04 28.57 0.00 0.00 "source" 0.04 28.57 0.00 0.00 "as.name" 0.02 14.29 0.02 14.29 "formals" 0.02 14.29 0.02 14.29 "make.names" 0.02 14.29 0.02 14.29 "parent.frame" 0.02 14.29 0.02 14.29 "pmatch" 0.02 14.29 0.02 14.29 "anova" 0.02 14.29 0.00 0.00 "anova.glm" 0.02 14.29 0.00 0.00 "data.frame" 0.02 14.29 0.00 0.00 "deParse" 0.02 14.29 0.00 0.00 ".deparseOpts" 0.02 14.29 0.00 0.00 ".getXlevels" 0.02 14.29 0.00 0.00 "glm" 0.02 14.29 0.00 0.00 "%in%" 0.02 14.29 0.00 0.00 "match.call" 0.02 14.29 0.00 0.00 "mode" 0.02 14.29 0.00 0.00 "NextMethod" 0.02 14.29 0.00 0.00 "paste" 0.02 14.29 0.00 0.00 "sapply" 0.02 14.29 0.00 0.00 "str.data.frame" 0.02 14.29 0.00 0.00 "summary" 0.02 14.29 0.00 0.00 "%w/o%" 0.02 14.29 0.00 0.00 $sample.interval [1] 0.02 $sampling.time [1] 0.14
      
      





たくさんの情報!



注:sample.interval = 0.02は、Rprofileが呼び出しスタックを分析して測定を行う頻度を決定します。 T.O. Rprofileは調査を通じてのみ機能します。 したがって、コードをプロファイルするたびにsummaryRprofが異なる場合があります。 数値にわずかな違いがあるだけでなく、たとえば、要素が欠落している場合もあります。 たとえば、最初の1つはコードの実行中に誤って測定が行われ、別の開始では2つの測定の間に実行が行われたためです。



ポイントプロファイリングのケース



適切なケースを見てみましょう。 次の関数があると仮定します。

 Do_1 <- function() { combn(1:20, 5) for (i in 1:15) Do_2() for (i in 1:25) Do_4() } Do_2 <- function() { combn(1:15, 5) for (i in 1:5) Do_3() } Do_3 <- function() { combn(1:14, 5) for (i in 1:20) Do_4() } Do_4 <- function() { paste(1:1000) combn(1:11, 5) }
      
      





はい、それはひどく無意味ですが、この例では素晴らしいです:それらを完了するには時間がかかります。



それでは、プロファイルしてみましょう。

 Do_1 : Rprof(tmp <- tempfile()) Do_1() Rprof(NULL) summaryRprof(tmp)
      
      





次のようになります。

 $by.self self.time self.pct total.time total.pct "combn" 1.24 71.26 1.28 73.56 "paste" 0.46 26.44 0.46 26.44 "matrix" 0.04 2.30 0.04 2.30 $by.total total.time total.pct self.time self.pct "Do_1" 1.74 100.00 0.00 0.00 "Do_2" 1.72 98.85 0.00 0.00 "Do_3" 1.68 96.55 0.00 0.00 "Do_4" 1.48 85.06 0.00 0.00 "combn" 1.28 73.56 1.24 71.26 "paste" 0.46 26.44 0.46 26.44 "matrix" 0.04 2.30 0.04 2.30
      
      





素晴らしい。 combnの実行時間は約4分の3で、貼り付けには1分の4しかかからないことがわかります。



ちょっと待って:マトリックス? これはどこから来たのですか? この関数は、combinまたはpaste内で呼び出す必要があります。 マトリックスは合計時間の2.3%しかかからないため、問題はありません。 しかし、それを理解するのはまだ面白いですよね?



prof.treeを使用したデータ分析のプロファイリング



CRANまたはgithubで利用可能なArt。Klevtsov prof.treeパッケージは、このデータを分析する別の方法を提供します。 プロファイリングデータをツリーで表示できます。

 library(prof.tree) pr <- prof.tree(tmp) print(pr, limit = NULL)
      
      





結果は次のようになります。

 levelName real percent env 1 calls 1.74 100.0 % 2 °--Do_1 1.74 100.0 % R_GlobalEnv 3 ¦--Do_2 1.72 98.9 % R_GlobalEnv 4 ¦ ¦--Do_3 1.68 96.6 % R_GlobalEnv 5 ¦ ¦ ¦--combn 0.22 12.6 % utils 6 ¦ ¦ ¦ °--matrix 0.02 1.1 % base 7 ¦ ¦ °--Do_4 1.46 83.9 % R_GlobalEnv 8 ¦ ¦ ¦--combn 1.02 58.6 % utils 9 ¦ ¦ ¦ °--matrix 0.02 1.1 % base 10 ¦ ¦ °--paste 0.44 25.3 % base 11 ¦ °--combn 0.04 2.3 % utils 12 °--Do_4 0.02 1.1 % R_GlobalEnv 13 °--paste 0.02 1.1 % base
      
      





サプライズ! マトリックスは、ペーストからではなく、combinから呼び出されます!



注:prはdata.tree構造であるため、すべてのdata.tree操作を使用できます。 たとえば、特定の機能に関する情報を(名前で)収集できます。

 library(data.tree) SumByFunction <- function(name) { sum(pr$Get("real", filterFun = function(node) node$name == name))/pr$real } SumByFunction("combn")
      
      





上記と同様に、これにより73.56%が得られます。



また、たとえば5%を超えるパーセンテージを持つすべてのサブツリーを削除することにより、表示される頂点の数を制限することもできます。

 print(pr, limit = NULL, pruneFun = function(x) x$percent > 0.05)
      
      





結果は次のとおりです。

 levelName real percent env 1 calls 1.74 100.0 % 2 °--Do_1 1.74 100.0 % R_GlobalEnv 3 °--Do_2 1.72 98.9 % R_GlobalEnv 4 °--Do_3 1.68 96.6 % R_GlobalEnv 5 ¦--combn 0.22 12.6 % utils 6 °--Do_4 1.46 83.9 % R_GlobalEnv 7 ¦--combn 1.02 58.6 % utils 8 °--paste 0.44 25.3 % base
      
      





または、data.treeグラフィックツールを使用してこれを視覚化できます。

 cols <- colorRampPalette(c("green", "red"))(101) SetNodeStyle(pr, style = "filled,rounded", shape = "box", fontname = "helvetica", fillcolor = function(node) cols[round(node$percent * 100) + 1], tooltip = function(node) node$real) plot(pr)
      
      





グラフは次のようになります。

画像







All Articles