<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="http://www.r-bloggers.com/r-profiling/"></div></div><div><a data-url="http://www.r-bloggers.com/r-profiling/" data-counturl="http://www.r-bloggers.com/r-profiling/" data-count="horizontal" data-text="R profiling" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://ipub.com/r-profiling/"> R – ipub</a></strong>, and kindly contributed to <a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers)</a> </div>
<h2>Profiling in R</h2>
<p>R has a built in performance and memory profiling facility: Rprof. Type 
<pre>?Rprof</pre>
<p> into your console to learn more.</p>
<p>The way the profiler works is as follows:</p>
<ol>
<li>you start the profiler by calling Rprof, providing a filename where the profiling data should be stored</li>
<li>you call the R functions that you want to analyse</li>
<li>you call Rprof(NULL) to stop the profiler</li>
<li>you analyse the file created by Rprof, typically using 
<pre>summaryRprof</pre>
</li>
</ol>
<p>For example:</p>
<pre>Rprof(tmp &lt;- tempfile())
example(glm)
Rprof()
summaryRprof(tmp)
unlink(tmp)</pre>
<p>The output looks like this:</p>
<pre>$by.self
               self.time self.pct total.time total.pct
&quot;str.default&quot;       0.02    14.29       0.10     71.43
&quot;deparse&quot;           0.02    14.29       0.04     28.57
&quot;as.name&quot;           0.02    14.29       0.02     14.29
&quot;formals&quot;           0.02    14.29       0.02     14.29
&quot;make.names&quot;        0.02    14.29       0.02     14.29
&quot;parent.frame&quot;      0.02    14.29       0.02     14.29
&quot;pmatch&quot;            0.02    14.29       0.02     14.29

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

$sample.interval
[1] 0.02

$sampling.time
[1] 0.14</pre>
<p>A lot of information!</p>
<p>As a side note, the sample.interval of 0.02 indicates the frequency with which Rprofile analysis the call stack and takes measures. So, Rprofile works entirely through polling. As a result, summaryRprof may look different each time you profile code. Not only slight differences in the numbers, but also e.g. elements missing, for instance because in one run the measurement was done by chance while, say, mode was executing, whereas in another run mode slipped between two measurements.</p>
<h2>Stylized profiling example</h2>
<p>Let’s look at a stylized example. Assume you have the following functions:</p>
<pre>Do_1 &lt;- function() {
  combn(1:20, 5)
  for (i in 1:15) Do_2()
  for (i in 1:25) Do_4()
}

Do_2 &lt;- function() {
  combn(1:15, 5)
  for (i in 1:5) Do_3()
}

Do_3 &lt;- function() {
  combn(1:14, 5)
  for (i in 1:20) Do_4()
}

Do_4 &lt;- function() {
  paste(1:1000)
  combn(1:11, 5)
}</pre>
<p>Ugly and pointless, true, but for the sake of this example they serve their purpose: it will take time to execute them.</p>
<p>So, again, let’s profile 
<pre>Do_1</pre>
<p> :</p>
<pre>Rprof(tmp &lt;- tempfile())
Do_1()
Rprof(NULL)
summaryRprof(tmp)</pre>
<p>Which looks like this:</p>
<pre>$by.self
         self.time self.pct total.time total.pct
&quot;combn&quot;       1.24    71.26       1.28     73.56
&quot;paste&quot;       0.46    26.44       0.46     26.44
&quot;matrix&quot;      0.04     2.30       0.04      2.30

$by.total
         total.time total.pct self.time self.pct
&quot;Do_1&quot;         1.74    100.00      0.00     0.00
&quot;Do_2&quot;         1.72     98.85      0.00     0.00
&quot;Do_3&quot;         1.68     96.55      0.00     0.00
&quot;Do_4&quot;         1.48     85.06      0.00     0.00
&quot;combn&quot;        1.28     73.56      1.24    71.26
&quot;paste&quot;        0.46     26.44      0.46    26.44
&quot;matrix&quot;       0.04      2.30      0.04     2.30</pre>
<p>Nice. We see that combn uses about three quarter of computing time, while paste uses only one quarter.</p>
<p>But hang on: matrix? Where does that come from? Must be either combn or paste calling that internally. No big deal here, as matrix only uses 2.3% of total time. But still, would be interesting to understand this, right?</p>
<h2>Analysis of profiling data with prof.tree</h2>
<p>Luckily, the prof.tree package by Artem Kelvtsov, which is available from <a target="_blank" href="https://cran.r-project.org/web/packages/prof.tree/index.html">CRAN </a>or from <a target="_blank" href="https://github.com/artemklevtsov/prof.tree">github</a>, provides an alternative to analyzing that data. It displays profiling information as a tree:</p>
<pre>library(prof.tree)
pr &lt;- prof.tree(tmp)
print(pr, limit = NULL)</pre>
<p>This will print like so:</p>
<pre>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</pre>
<p>Surprise! matrix was called from combn, and not from paste!</p>
<p>Note that pr is a <a target="_blank" href="http://ipub.com/data-tree/">data.tree</a> structure, so all data.tree operations are available. For example, we can sum up specific functions by name:</p>
<pre>library(data.tree)
SumByFunction &lt;- function(name) {
  sum(pr$Get(&quot;real&quot;, filterFun = function(node) node$name == name))/pr$real
}

SumByFunction(&quot;combn&quot;)</pre>
<p>And, just as above, this gives us 73.56%.</p>
<p>Also, we can limit the nodes that are printed, by pruning out all subtrees whose percent is larger than, say, 5%:</p>
<pre>print(pr, limit = NULL, pruneFun = function(x) x$percent > 0.05)</pre>
<p>Et voilà:</p>
<pre>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</pre>
<p>Or we can use the data.tree plot facility to visualize this:</p>
<pre>cols &lt;- colorRampPalette(c(&quot;green&quot;, &quot;red&quot;))(101)
SetNodeStyle(pr, 
             style = &quot;filled,rounded&quot;, 
             shape = &quot;box&quot;,
             fontname = &quot;helvetica&quot;,
             fillcolor = function(node) cols[round(node$percent * 100) + 1],
             tooltip = function(node) node$real)

plot(pr)</pre>
<p>This will plot like so:</p>
<p><a target="_blank" href="http://i2.wp.com/ipub.com/wp-content/uploads/2016/06/plotRprofile.png"><img sizes="(max-width: 239px) 100vw, 239px" srcset="http://i2.wp.com/ipub.com/wp-content/uploads/2016/06/plotRprofile.png?resize=239%2C441 239w, http://ipub.com/wp-content/uploads/2016/06/plotRprofile-163x300.png 163w" alt="plot profiling" class="wp-image-652" src="http://i2.wp.com/ipub.com/wp-content/uploads/2016/06/plotRprofile.png?resize=239%2C441" data-recalc-dims="1"></a></p>
<p>If you like what you see, make sure you show some love by starring Artem’s package on <a target="_blank" href="https://github.com/artemklevtsov/prof.tree">github</a>.</p>
<p>The post <a target="_blank" rel="nofollow" href="http://ipub.com/r-profiling/">R profiling</a> appeared first on <a target="_blank" rel="nofollow" href="http://ipub.com/">ipub</a>.</p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="http://www.r-bloggers.com/r-profiling/"></div></div><div><a data-url="http://www.r-bloggers.com/r-profiling/" data-counturl="http://www.r-bloggers.com/r-profiling/" data-count="vertical" data-text="R profiling" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://ipub.com/r-profiling/"> R – ipub</a></strong>.</div>
<hr>
<a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="http://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="http://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="http://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="http://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="http://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="http://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="http://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="http://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="http://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="http://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="http://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="http://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="http://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="http://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="http://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="http://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/IojAr6bHVUw"></a></div>