ruby-prof 0.15.8 → 0.15.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +5 -0
  3. data/README.rdoc +187 -185
  4. data/doc/LICENSE.html +114 -0
  5. data/doc/README_rdoc.html +544 -0
  6. data/doc/Rack.html +95 -0
  7. data/doc/Rack/RubyProf.html +223 -0
  8. data/doc/RubyProf.html +961 -0
  9. data/doc/RubyProf/AbstractPrinter.html +546 -0
  10. data/doc/RubyProf/AggregateCallInfo.html +551 -0
  11. data/doc/RubyProf/CallInfo.html +639 -0
  12. data/doc/RubyProf/CallInfoPrinter.html +120 -0
  13. data/doc/RubyProf/CallInfoVisitor.html +198 -0
  14. data/doc/RubyProf/CallStackPrinter.html +1121 -0
  15. data/doc/RubyProf/CallTreePrinter.html +359 -0
  16. data/doc/RubyProf/Cmd.html +631 -0
  17. data/doc/RubyProf/DotPrinter.html +257 -0
  18. data/doc/RubyProf/FlatPrinter.html +163 -0
  19. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +208 -0
  20. data/doc/RubyProf/GraphHtmlPrinter.html +552 -0
  21. data/doc/RubyProf/GraphPrinter.html +139 -0
  22. data/doc/RubyProf/MethodInfo.html +745 -0
  23. data/doc/RubyProf/MultiPrinter.html +358 -0
  24. data/doc/RubyProf/Profile.html +713 -0
  25. data/doc/RubyProf/ProfileTask.html +490 -0
  26. data/doc/RubyProf/Thread.html +268 -0
  27. data/doc/created.rid +13 -13
  28. data/doc/examples/flat_txt.html +138 -0
  29. data/doc/examples/graph_html.html +909 -0
  30. data/doc/examples/graph_txt.html +247 -0
  31. data/doc/images/add.png +0 -0
  32. data/doc/images/arrow_up.png +0 -0
  33. data/doc/images/brick.png +0 -0
  34. data/doc/images/brick_link.png +0 -0
  35. data/doc/images/bug.png +0 -0
  36. data/doc/images/bullet_black.png +0 -0
  37. data/doc/images/bullet_toggle_minus.png +0 -0
  38. data/doc/images/bullet_toggle_plus.png +0 -0
  39. data/doc/images/date.png +0 -0
  40. data/doc/images/delete.png +0 -0
  41. data/doc/images/find.png +0 -0
  42. data/doc/images/macFFBgHack.png +0 -0
  43. data/doc/images/package.png +0 -0
  44. data/doc/images/page_green.png +0 -0
  45. data/doc/images/page_white_text.png +0 -0
  46. data/doc/images/page_white_width.png +0 -0
  47. data/doc/images/plugin.png +0 -0
  48. data/doc/images/ruby.png +0 -0
  49. data/doc/images/tag_blue.png +0 -0
  50. data/doc/images/tag_green.png +0 -0
  51. data/doc/images/transparent.png +0 -0
  52. data/doc/images/wrench.png +0 -0
  53. data/doc/images/wrench_orange.png +0 -0
  54. data/doc/images/zoom.png +0 -0
  55. data/doc/index.html +571 -0
  56. data/doc/js/navigation.js.gz +0 -0
  57. data/doc/js/search_index.js +1 -1
  58. data/doc/js/search_index.js.gz +0 -0
  59. data/doc/js/searcher.js.gz +0 -0
  60. data/doc/table_of_contents.html +893 -0
  61. data/examples/flat.txt +50 -55
  62. data/examples/graph.html +823 -823
  63. data/examples/graph.txt +139 -170
  64. data/ext/ruby_prof/extconf.rb +6 -1
  65. data/lib/ruby-prof/aggregate_call_info.rb +17 -11
  66. data/lib/ruby-prof/call_info.rb +2 -17
  67. data/lib/ruby-prof/method_info.rb +6 -22
  68. data/lib/ruby-prof/printers/graph_html_printer.rb +0 -2
  69. data/lib/ruby-prof/printers/graph_printer.rb +4 -6
  70. data/lib/ruby-prof/rack.rb +7 -0
  71. data/lib/ruby-prof/thread.rb +0 -4
  72. data/lib/ruby-prof/version.rb +1 -1
  73. data/ruby-prof.gemspec +1 -1
  74. data/test/basic_test.rb +26 -26
  75. data/test/issue137_test.rb +63 -0
  76. data/test/measure_allocations_test.rb +4 -3
  77. data/test/measure_cpu_time_test.rb +6 -6
  78. data/test/measure_process_time_test.rb +8 -8
  79. data/test/pause_resume_test.rb +9 -9
  80. data/test/printers_test.rb +1 -1
  81. data/test/printing_recursive_graph_test.rb +127 -0
  82. data/test/rack_test.rb +49 -1
  83. data/test/recursive_test.rb +41 -37
  84. data/test/test_helper.rb +93 -0
  85. metadata +59 -5
@@ -0,0 +1,114 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta charset="UTF-8">
6
+
7
+ <title>LICENSE - ruby-prof</title>
8
+
9
+ <script type="text/javascript">
10
+ var rdoc_rel_prefix = "./";
11
+ </script>
12
+
13
+ <script src="./js/jquery.js"></script>
14
+ <script src="./js/darkfish.js"></script>
15
+
16
+ <link href="./css/fonts.css" rel="stylesheet">
17
+ <link href="./css/rdoc.css" rel="stylesheet">
18
+
19
+
20
+
21
+ <body id="top" role="document" class="file">
22
+ <nav role="navigation">
23
+ <div id="project-navigation">
24
+ <div id="home-section" role="region" title="Quick navigation" class="nav-section">
25
+ <h2>
26
+ <a href="./index.html" rel="home">Home</a>
27
+ </h2>
28
+
29
+ <div id="table-of-contents-navigation">
30
+ <a href="./table_of_contents.html#pages">Pages</a>
31
+ <a href="./table_of_contents.html#classes">Classes</a>
32
+ <a href="./table_of_contents.html#methods">Methods</a>
33
+ </div>
34
+ </div>
35
+
36
+ <div id="search-section" role="search" class="project-section initially-hidden">
37
+ <form action="#" method="get" accept-charset="utf-8">
38
+ <div id="search-field-wrapper">
39
+ <input id="search-field" role="combobox" aria-label="Search"
40
+ aria-autocomplete="list" aria-controls="search-results"
41
+ type="text" name="search" placeholder="Search" spellcheck="false"
42
+ title="Type to search, Up and Down to navigate, Enter to load">
43
+ </div>
44
+
45
+ <ul id="search-results" aria-label="Search Results"
46
+ aria-busy="false" aria-expanded="false"
47
+ aria-atomic="false" class="initially-hidden"></ul>
48
+ </form>
49
+ </div>
50
+
51
+ </div>
52
+
53
+
54
+
55
+ <div id="project-metadata">
56
+ <div id="fileindex-section" class="nav-section">
57
+ <h3>Pages</h3>
58
+
59
+ <ul class="link-list">
60
+
61
+ <li><a href="./LICENSE.html">LICENSE</a>
62
+
63
+ <li><a href="./README_rdoc.html">README</a>
64
+
65
+ <li><a href="./examples/flat_txt.html">flat</a>
66
+
67
+ <li><a href="./examples/graph_html.html">graph.html</a>
68
+
69
+ <li><a href="./examples/graph_txt.html">graph</a>
70
+
71
+ </ul>
72
+ </div>
73
+
74
+ </div>
75
+ </nav>
76
+
77
+ <main role="main" aria-label="Page LICENSE">
78
+
79
+ <p>Copyright (C) 2005 - 2014 Shugo Maeda &lt;shugo@ruby-lang.org&gt; and
80
+ Charlie Savage &lt;cfis@savagexi.com&gt; Copyright (C) 2010 - 2014 Stefan
81
+ Kaes &lt;skaes@railsepxress.de&gt; All rights reserved.</p>
82
+
83
+ <p>Redistribution and use in source and binary forms, with or without
84
+ modification, are permitted provided that the following conditions are met:</p>
85
+ <ol><li>
86
+ <p>Redistributions of source code must retain the above copyright notice, this
87
+ list of conditions and the following disclaimer.</p>
88
+ </li><li>
89
+ <p>Redistributions in binary form must reproduce the above copyright notice,
90
+ this list of conditions and the following disclaimer in the documentation
91
+ and/or other materials provided with the distribution.</p>
92
+ </li></ol>
93
+
94
+ <p>THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS&#39;&#39;
95
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
98
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
100
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
101
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
104
+ DAMAGE.</p>
105
+ </main>
106
+
107
+
108
+
109
+ <footer id="validator-badges" role="contentinfo">
110
+ <p><a href="http://validator.w3.org/check/referer">Validate</a>
111
+ <p>Generated by <a href="http://docs.seattlerb.org/rdoc/">RDoc</a> 4.2.0.
112
+ <p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
113
+ </footer>
114
+
@@ -0,0 +1,544 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta charset="UTF-8">
6
+
7
+ <title>README - ruby-prof</title>
8
+
9
+ <script type="text/javascript">
10
+ var rdoc_rel_prefix = "./";
11
+ </script>
12
+
13
+ <script src="./js/jquery.js"></script>
14
+ <script src="./js/darkfish.js"></script>
15
+
16
+ <link href="./css/fonts.css" rel="stylesheet">
17
+ <link href="./css/rdoc.css" rel="stylesheet">
18
+
19
+
20
+
21
+ <body id="top" role="document" class="file">
22
+ <nav role="navigation">
23
+ <div id="project-navigation">
24
+ <div id="home-section" role="region" title="Quick navigation" class="nav-section">
25
+ <h2>
26
+ <a href="./index.html" rel="home">Home</a>
27
+ </h2>
28
+
29
+ <div id="table-of-contents-navigation">
30
+ <a href="./table_of_contents.html#pages">Pages</a>
31
+ <a href="./table_of_contents.html#classes">Classes</a>
32
+ <a href="./table_of_contents.html#methods">Methods</a>
33
+ </div>
34
+ </div>
35
+
36
+ <div id="search-section" role="search" class="project-section initially-hidden">
37
+ <form action="#" method="get" accept-charset="utf-8">
38
+ <div id="search-field-wrapper">
39
+ <input id="search-field" role="combobox" aria-label="Search"
40
+ aria-autocomplete="list" aria-controls="search-results"
41
+ type="text" name="search" placeholder="Search" spellcheck="false"
42
+ title="Type to search, Up and Down to navigate, Enter to load">
43
+ </div>
44
+
45
+ <ul id="search-results" aria-label="Search Results"
46
+ aria-busy="false" aria-expanded="false"
47
+ aria-atomic="false" class="initially-hidden"></ul>
48
+ </form>
49
+ </div>
50
+
51
+ </div>
52
+
53
+
54
+ <div class="nav-section">
55
+ <h3>Table of Contents</h3>
56
+
57
+ <ul class="link-list" role="directory">
58
+ <li><a href="#label-ruby-prof">ruby-prof</a>
59
+ <li><a href="#label-Overview">Overview</a>
60
+ <li><a href="#label-Requirements">Requirements</a>
61
+ <li><a href="#label-Install">Install</a>
62
+ <li><a href="#label-Usage">Usage</a>
63
+ <li><a href="#label-ruby-prof+executable">ruby-prof executable</a>
64
+ <li><a href="#label-ruby-prof+API">ruby-prof API</a>
65
+ <li><a href="#label-Method+and+Thread+Elimination">Method and Thread Elimination</a>
66
+ <li><a href="#label-Profiling+Rails">Profiling Rails</a>
67
+ <li><a href="#label-Reports">Reports</a>
68
+ <li><a href="#label-Printers">Printers</a>
69
+ <li><a href="#label-Measurements">Measurements</a>
70
+ <li><a href="#label-Multi-threaded+Applications">Multi-threaded Applications</a>
71
+ <li><a href="#label-Performance">Performance</a>
72
+ <li><a href="#label-License">License</a>
73
+ <li><a href="#label-Development">Development</a>
74
+ </ul>
75
+ </div>
76
+
77
+
78
+ <div id="project-metadata">
79
+ <div id="fileindex-section" class="nav-section">
80
+ <h3>Pages</h3>
81
+
82
+ <ul class="link-list">
83
+
84
+ <li><a href="./LICENSE.html">LICENSE</a>
85
+
86
+ <li><a href="./README_rdoc.html">README</a>
87
+
88
+ <li><a href="./examples/flat_txt.html">flat</a>
89
+
90
+ <li><a href="./examples/graph_html.html">graph.html</a>
91
+
92
+ <li><a href="./examples/graph_txt.html">graph</a>
93
+
94
+ </ul>
95
+ </div>
96
+
97
+ </div>
98
+ </nav>
99
+
100
+ <main role="main" aria-label="Page README.rdoc">
101
+
102
+ <h1 id="label-ruby-prof">ruby-prof<span><a href="#label-ruby-prof">&para;</a> <a href="#top">&uarr;</a></span></h1>
103
+
104
+ <p><a href="https://travis-ci.org/ruby-prof/ruby-prof"><img
105
+ src="https://travis-ci.org/ruby-prof/ruby-prof.png?branch=master"
106
+ alt="Build Status" /></a></p>
107
+
108
+ <h2 id="label-Overview">Overview<span><a href="#label-Overview">&para;</a> <a href="#top">&uarr;</a></span></h2>
109
+
110
+ <p>ruby-prof is a fast code profiler for MRI Ruby. Its features include:</p>
111
+ <ul><li>
112
+ <p>Speed - it is a C extension and therefore many times faster than the
113
+ standard Ruby profiler.</p>
114
+ </li><li>
115
+ <p>Modes - Ruby prof can measure a number of different parameters, including
116
+ call times, memory usage and object allocations.</p>
117
+ </li><li>
118
+ <p>Reports - can generate text and cross-referenced html reports</p>
119
+ <ul><li>
120
+ <p>Flat Profiles - similar to the reports generated by the standard Ruby
121
+ profiler</p>
122
+ </li><li>
123
+ <p>Graph profiles - similar to GProf, these show how long a method runs, which
124
+ methods call it and which methods it calls.</p>
125
+ </li><li>
126
+ <p>Call tree profiles - outputs results in the calltree format suitable for
127
+ the KCacheGrind profiling tool.</p>
128
+ </li><li>
129
+ <p>Many more – see reports section of this README.</p>
130
+ </li></ul>
131
+ </li><li>
132
+ <p>Threads - supports profiling multiple threads simultaneously</p>
133
+ </li></ul>
134
+
135
+ <h2 id="label-Requirements">Requirements<span><a href="#label-Requirements">&para;</a> <a href="#top">&uarr;</a></span></h2>
136
+
137
+ <p>ruby-prof requires Ruby 1.9.3 or higher. Please note some ruby releases
138
+ have known bugs which cause ruby-prof problems, like incorrect
139
+ measurements. We suggest to use the latest minor patch level release if
140
+ possible. In particular, on the 2.1 branch of ruby you should use 2.1.7.</p>
141
+
142
+ <p>If you are running Linux or Unix you&#39;ll need a C compiler so the
143
+ extension can be compiled when it is installed.</p>
144
+
145
+ <p>If you are running Windows, then you may need to install the Windows
146
+ specific RubyGem which includes an already built extension (see Install
147
+ section).</p>
148
+
149
+ <h2 id="label-Install">Install<span><a href="#label-Install">&para;</a> <a href="#top">&uarr;</a></span></h2>
150
+
151
+ <p>The easiest way to install ruby-prof is by using Ruby Gems. To install:</p>
152
+
153
+ <pre class="ruby"><span class="ruby-identifier">gem</span> <span class="ruby-identifier">install</span> <span class="ruby-identifier">ruby</span><span class="ruby-operator">-</span><span class="ruby-identifier">prof</span>
154
+ </pre>
155
+
156
+ <p>If you&#39;re on windows then please install the devkit first so that it
157
+ can compile.</p>
158
+
159
+ <h2 id="label-Usage">Usage<span><a href="#label-Usage">&para;</a> <a href="#top">&uarr;</a></span></h2>
160
+
161
+ <p>There are two ways of running ruby-prof, via the command line or via its
162
+ API.</p>
163
+
164
+ <h3 id="label-ruby-prof+executable">ruby-prof executable<span><a href="#label-ruby-prof+executable">&para;</a> <a href="#top">&uarr;</a></span></h3>
165
+
166
+ <p>The first is to use ruby-prof to run the Ruby program you want to profile.
167
+ For more information refer to the documentation of the ruby-prof command.</p>
168
+
169
+ <h3 id="label-ruby-prof+API">ruby-prof API<span><a href="#label-ruby-prof+API">&para;</a> <a href="#top">&uarr;</a></span></h3>
170
+
171
+ <p>The second way is to use the ruby-prof API to profile particular segments
172
+ of code.</p>
173
+
174
+ <pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">&#39;ruby-prof&#39;</span>
175
+
176
+ <span class="ruby-comment"># profile the code</span>
177
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">start</span>
178
+ <span class="ruby-comment"># ... code to profile ...</span>
179
+ <span class="ruby-identifier">result</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">stop</span>
180
+
181
+ <span class="ruby-comment"># print a flat profile to text</span>
182
+ <span class="ruby-identifier">printer</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">FlatPrinter</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">result</span>)
183
+ <span class="ruby-identifier">printer</span>.<span class="ruby-identifier">print</span>(<span class="ruby-constant">STDOUT</span>)
184
+ </pre>
185
+
186
+ <p>Alternatively, you can use a block to tell ruby-prof what to profile:</p>
187
+
188
+ <pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">&#39;ruby-prof&#39;</span>
189
+
190
+ <span class="ruby-comment"># profile the code</span>
191
+ <span class="ruby-identifier">result</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">profile</span> <span class="ruby-keyword">do</span>
192
+ <span class="ruby-comment"># ... code to profile ...</span>
193
+ <span class="ruby-keyword">end</span>
194
+
195
+ <span class="ruby-comment"># print a graph profile to text</span>
196
+ <span class="ruby-identifier">printer</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">GraphPrinter</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">result</span>)
197
+ <span class="ruby-identifier">printer</span>.<span class="ruby-identifier">print</span>(<span class="ruby-constant">STDOUT</span>, {})
198
+ </pre>
199
+
200
+ <p>ruby-prof also supports pausing and resuming profiling runs.</p>
201
+
202
+ <pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">&#39;ruby-prof&#39;</span>
203
+
204
+ <span class="ruby-comment"># profile the code</span>
205
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">start</span>
206
+ <span class="ruby-comment"># ... code to profile ...</span>
207
+
208
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">pause</span>
209
+ <span class="ruby-comment"># ... other code ...</span>
210
+
211
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">resume</span>
212
+ <span class="ruby-comment"># ... code to profile ...</span>
213
+ <span class="ruby-identifier">result</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">stop</span>
214
+ </pre>
215
+
216
+ <p>Note that resume will automatically call start if a profiling run has not
217
+ yet started. In addition, resume can also take a block:</p>
218
+
219
+ <pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">&#39;ruby-prof&#39;</span>
220
+
221
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">resume</span> <span class="ruby-keyword">do</span>
222
+ <span class="ruby-comment"># ... code to profile...</span>
223
+ <span class="ruby-keyword">end</span>
224
+
225
+ <span class="ruby-identifier">data</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">stop</span>
226
+ </pre>
227
+
228
+ <p>With this usage, resume will automatically call pause at the end of the
229
+ block.</p>
230
+
231
+ <h2 id="label-Method+and+Thread+Elimination">Method and Thread Elimination<span><a href="#label-Method+and+Thread+Elimination">&para;</a> <a href="#top">&uarr;</a></span></h2>
232
+
233
+ <p>ruby-prof supports eliminating specific methods and threads from profiling
234
+ results. This is useful for reducing connectivity in the call graph, making
235
+ it easier to identify the source of performance problems when using a graph
236
+ printer.</p>
237
+
238
+ <p>For example, consider <code>Integer#times</code>: it&#39;s hardly ever
239
+ useful to know how much time is spent in the method itself. We&#39;re much
240
+ more interested in how much the passed in block contributes to the time
241
+ spent in the method which contains the <code>Integer#times</code> call.</p>
242
+
243
+ <p>Methods are eliminated from the collected data by calling
244
+ <code>eliminate_methods!</code> on the profiling result, before submitting
245
+ it to a printer.</p>
246
+
247
+ <pre class="ruby"><span class="ruby-identifier">result</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">stop</span>
248
+ <span class="ruby-identifier">result</span>.<span class="ruby-identifier">eliminate_methods!</span>([<span class="ruby-node">/Integer#times/</span>])
249
+ </pre>
250
+
251
+ <p>The argument given to <code>eliminate_methods!</code> is either an array of
252
+ regular expressions, or the name of a file containing a list of regular
253
+ expressions (line separated text).</p>
254
+
255
+ <p>After eliminating methods the resulting profile will appear exactly as if
256
+ those methods had been inlined at their call sites.</p>
257
+
258
+ <p>In a similar manner, threads can be excluded so they are not profiled at
259
+ all. To do this, pass an array of threads to exclude to ruby-prof:</p>
260
+
261
+ <pre class="ruby"><span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-identifier">exclude_threads</span> = [ <span class="ruby-identifier">thread2</span> ]
262
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">start</span>
263
+ </pre>
264
+
265
+ <p>Note that the excluded threads must be specified <strong>before</strong>
266
+ profiling.</p>
267
+
268
+ <h2 id="label-Profiling+Rails">Profiling Rails<span><a href="#label-Profiling+Rails">&para;</a> <a href="#top">&uarr;</a></span></h2>
269
+
270
+ <p>To profile a Rails application it is vital to run it using production like
271
+ settings (cache classes, cache view lookups, etc.). Otherwise, Rail&#39;s
272
+ dependency loading code will overwhelm any time spent in the application
273
+ itself (our tests show that Rails dependency loading causes a roughly 6x
274
+ slowdown). The best way to do this is create a new Rails environment,
275
+ profile.rb.</p>
276
+
277
+ <p>So to profile Rails:</p>
278
+ <ol><li>
279
+ <p>Create a new profile.rb environment. Make sure to turn on
280
+ <code>cache_classes</code> and <code>cache_template_loading</code>.
281
+ Otherwise your profiling results will be overwhelemed by the time Rails
282
+ spends loading required files. You should likely turn off caching.</p>
283
+ </li><li>
284
+ <p>Add the ruby-prof to your gemfile:</p>
285
+
286
+ <pre class="ruby"><span class="ruby-identifier">group</span> :<span class="ruby-identifier">profile</span> <span class="ruby-keyword">do</span>
287
+ <span class="ruby-identifier">gem</span> <span class="ruby-string">&#39;ruby-prof&#39;</span>
288
+ <span class="ruby-keyword">end</span>
289
+ </pre>
290
+ </li><li>
291
+ <p>Add the ruby prof rack adapter to your middleware stack. One way to do
292
+ this is by adding the following code to <code>config.ru</code>:</p>
293
+
294
+ <pre class="ruby"><span class="ruby-keyword">if</span> <span class="ruby-constant">Rails</span>.<span class="ruby-identifier">env</span>.<span class="ruby-identifier">profile?</span>
295
+ <span class="ruby-identifier">use</span> <span class="ruby-constant">Rack</span><span class="ruby-operator">::</span><span class="ruby-constant">RubyProf</span>, :<span class="ruby-identifier">path</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-string">&#39;/temp/profile&#39;</span>
296
+ <span class="ruby-keyword">end</span>
297
+ </pre>
298
+
299
+ <p>The path is where you want profiling results to be stored. By default the
300
+ rack adapter will generate a html call graph report and flat text report.</p>
301
+ </li><li>
302
+ <p>Now make a request to your running server. New profiling information will
303
+ be generated for each request. Note that each request will overwrite the
304
+ profiling reports created by the previous request!</p>
305
+ </li></ol>
306
+
307
+ <h2 id="label-Reports">Reports<span><a href="#label-Reports">&para;</a> <a href="#top">&uarr;</a></span></h2>
308
+
309
+ <p>ruby-prof can generate a number of different reports:</p>
310
+ <ul><li>
311
+ <p>Flat Reports</p>
312
+ </li><li>
313
+ <p>Graph Reports</p>
314
+ </li><li>
315
+ <p>HTML Graph Reports</p>
316
+ </li><li>
317
+ <p>Call graphs</p>
318
+ </li><li>
319
+ <p>Call stack reports</p>
320
+ </li><li>
321
+ <p>More!</p>
322
+ </li></ul>
323
+
324
+ <p>Flat profiles show the overall time spent in each method. They are a good
325
+ way of quickly identifying which methods take the most time. An example of
326
+ a flat profile and an explanation can be found in <a
327
+ href="http://github.com/ruby-prof/ruby-prof/tree/master/examples/flat.txt">examples/flat.txt</a>.</p>
328
+
329
+ <p>There are several varieties of these - run <code>ruby-prof --help</code></p>
330
+
331
+ <p>Graph profiles also show the overall time spent in each method. In
332
+ addition, they also show which methods call the current method and which
333
+ methods its calls. Thus they are good for understanding how methods gets
334
+ called and provide insight into the flow of your program. An example text
335
+ graph profile is located at <a
336
+ href="http://github.com/ruby-prof/ruby-prof/tree/master/examples/graph.txt">examples/graph.txt</a>.</p>
337
+
338
+ <p>HTML Graph profiles are the same as graph profiles, except output is
339
+ generated in hyper-linked HTML. Since graph profiles can be quite large,
340
+ the embedded links make it much easier to navigate the results. An example
341
+ html graph profile is located at <a
342
+ href="http://github.com/ruby-prof/ruby-prof/tree/master/examples/graph.html">examples/graph.html</a>.</p>
343
+
344
+ <p>Call graphs output results in the calltree profile format which is used by
345
+ KCachegrind. Call graph support was generously donated by Carl Shimer. More
346
+ information about the format can be found at the <a
347
+ href="http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindCalltreeFormat">KCachegrind</a>
348
+ site.</p>
349
+
350
+ <p>Call stack reports produce a HTML visualization of the time spent in each
351
+ execution path of the profiled code. An example can be found at <a
352
+ href="http://github.com/ruby-prof/ruby-prof/tree/master/examples/stack.html">examples/stack.html</a>.</p>
353
+
354
+ <p>Another good example: <a
355
+ href="http://twitpic.com/28z94a">twitpic.com/28z94a</a></p>
356
+
357
+ <p>Finally, there&#39;s a so called MultiPrinter which can generate several
358
+ reports in one profiling run. See <a
359
+ href="http://github.com/ruby-prof/ruby-prof/tree/master/examples/multi.stack.html">examples/multi.stack.html</a>.</p>
360
+
361
+ <p>There is also a graphviz .dot visualiser.</p>
362
+
363
+ <h2 id="label-Printers">Printers<span><a href="#label-Printers">&para;</a> <a href="#top">&uarr;</a></span></h2>
364
+
365
+ <p>Reports are created by printers. Supported printers include:</p>
366
+ <dl class="rdoc-list note-list"><dt><a href="RubyProf/FlatPrinter.html">RubyProf::FlatPrinter</a>
367
+ <dd>
368
+ <p>Creates a flat report in text format</p>
369
+ </dd><dt><a href="RubyProf/FlatPrinterWithLineNumbers.html">RubyProf::FlatPrinterWithLineNumbers</a>
370
+ <dd>
371
+ <p>Same as above but more verbose</p>
372
+ </dd><dt><a href="RubyProf/GraphPrinter.html">RubyProf::GraphPrinter</a>
373
+ <dd>
374
+ <p>Creates a call graph report in text format</p>
375
+ </dd><dt><a href="RubyProf/GraphHtmlPrinter.html">RubyProf::GraphHtmlPrinter</a>
376
+ <dd>
377
+ <p>Creates a call graph report in HTML (separate files per thread)</p>
378
+ </dd><dt><a href="RubyProf/DotPrinter.html">RubyProf::DotPrinter</a>
379
+ <dd>
380
+ <p>Creates a call graph report in GraphViz&#39;s DOT format which can be
381
+ converted to an image</p>
382
+ </dd><dt><a href="RubyProf/CallTreePrinter.html">RubyProf::CallTreePrinter</a>
383
+ <dd>
384
+ <p>Creates a call tree report compatible with KCachegrind</p>
385
+ </dd><dt><a href="RubyProf/CallStackPrinter.html">RubyProf::CallStackPrinter</a>
386
+ <dd>
387
+ <p>Creates a HTML visualization of the Ruby stack</p>
388
+ </dd><dt><a href="RubyProf/MultiPrinter.html">RubyProf::MultiPrinter</a>
389
+ <dd>
390
+ <p>Uses the other printers to create several reports in one profiling run</p>
391
+ </dd></dl>
392
+
393
+ <p>To use a printer:</p>
394
+
395
+ <pre class="ruby"><span class="ruby-identifier">result</span> = <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">stop</span>
396
+ <span class="ruby-identifier">printer</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">GraphPrinter</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">result</span>)
397
+ <span class="ruby-identifier">printer</span>.<span class="ruby-identifier">print</span>(<span class="ruby-constant">STDOUT</span>, :<span class="ruby-identifier">min_percent</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value">2</span>)
398
+ </pre>
399
+
400
+ <p>The first parameter is any writable IO object such as <code>STDOUT</code>
401
+ or a file. The second parameter, specifies the minimum percentage a method
402
+ must take to be printed. Percentages should be specified as integers in
403
+ the range 0 to 100. For more information please see the documentation for
404
+ the different printers.</p>
405
+
406
+ <p>The other option is <code>:print_file =&gt; true</code> (default false),
407
+ which adds the filename to the output (GraphPrinter only).</p>
408
+
409
+ <p><code>MultiPrinter</code> differs from the other printers in that it
410
+ requires a directory path and a basename for the files it produces.</p>
411
+
412
+ <pre class="ruby"><span class="ruby-identifier">printer</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">MultiPrinter</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">result</span>)
413
+ <span class="ruby-identifier">printer</span>.<span class="ruby-identifier">print</span>(:<span class="ruby-identifier">path</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-string">&quot;.&quot;</span>, :<span class="ruby-identifier">profile</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-string">&quot;profile&quot;</span>)
414
+ </pre>
415
+
416
+ <h2 id="label-Measurements">Measurements<span><a href="#label-Measurements">&para;</a> <a href="#top">&uarr;</a></span></h2>
417
+
418
+ <p>Depending on the mode and platform, ruby-prof can measure various aspects
419
+ of a Ruby program. Supported measurements include:</p>
420
+ <dl class="rdoc-list note-list"><dt>RubyProf::WALL_TIME
421
+ <dd>
422
+ <p>Wall time measures the real-world time elapsed between any two moments. If
423
+ there are other processes concurrently running on the system that use
424
+ significant CPU or disk time during a profiling run then the reported
425
+ results will be larger than expected.</p>
426
+ </dd><dt>RubyProf::PROCESS_TIME
427
+ <dd>
428
+ <p>Process time measures the time used by a process between any two moments.
429
+ It is unaffected by other processes concurrently running on the system.
430
+ Note that Windows does not support measuring process times.</p>
431
+ </dd><dt>RubyProf::CPU_TIME
432
+ <dd>
433
+ <p>CPU time uses the CPU clock counter to measure time. The returned values
434
+ are dependent on the correctly setting the CPU&#39;s frequency. This mode
435
+ is only supported on Pentium or PowerPC platforms (linux only).</p>
436
+ </dd><dt>RubyProf::ALLOCATIONS
437
+ <dd>
438
+ <p>Object allocation reports show how many objects each method in a program
439
+ allocates. This support was added by Sylvain Joyeux and requires a patched
440
+ Ruby interpreter. See below.</p>
441
+ </dd><dt>RubyProf::MEMORY
442
+ <dd>
443
+ <p>Memory usage reports show how much memory each method in a program uses.
444
+ This support was added by Alexander Dymo and requires a patched Ruby
445
+ interpreter. See below.</p>
446
+ </dd><dt>RubyProf::GC_TIME
447
+ <dd>
448
+ <p>Garbage collection time reports how much time is spent in Ruby&#39;s
449
+ garbage collector during a profiling session. This support was added by
450
+ Jeremy Kemper and requires a patched Ruby interpreter. See below.</p>
451
+ </dd><dt>RubyProf::GC_RUNS
452
+ <dd>
453
+ <p>Garbage collection runs report how many times Ruby&#39;s garbage collector
454
+ is invoked during a profiling session. This support was added by Jeremy
455
+ Kemper and requires a patched Ruby interpreter. See below.</p>
456
+ </dd></dl>
457
+
458
+ <p>All of the patches to Ruby are included in the railsexpress patchsets for
459
+ rvm, see <a
460
+ href="https://github.com/skaes/rvm-patchsets">github.com/skaes/rvm-patchsets</a></p>
461
+
462
+ <p>To set the measurement:</p>
463
+
464
+ <pre class="ruby"><span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">WALL_TIME</span>
465
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">PROCESS_TIME</span>
466
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">CPU_TIME</span>
467
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">ALLOCATIONS</span>
468
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">MEMORY</span>
469
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">GC_TIME</span>
470
+ <span class="ruby-constant">RubyProf</span>.<span class="ruby-identifier">measure_mode</span> = <span class="ruby-constant">RubyProf</span><span class="ruby-operator">::</span><span class="ruby-constant">GC_RUNS</span>
471
+ </pre>
472
+
473
+ <p>The default value is <code>RubyProf::WALL_TIME</code>.</p>
474
+
475
+ <p>You may also specify the measure mode by using the
476
+ <code>RUBY_PROF_MEASURE_MODE</code> environment variable:</p>
477
+
478
+ <pre class="ruby"><span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">wall</span>
479
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">process</span>
480
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">cpu</span>
481
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">allocations</span>
482
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">memory</span>
483
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">gc_time</span>
484
+ <span class="ruby-identifier">export</span> <span class="ruby-constant">RUBY_PROF_MEASURE_MODE</span>=<span class="ruby-identifier">gc_runs</span>
485
+ </pre>
486
+
487
+ <p>On Linux, process time is measured using the clock method provided by the C
488
+ runtime library. Note that the clock method does not report time spent in
489
+ the kernel or child processes and therefore does not measure time spent in
490
+ methods such as Kernel.sleep method. If you need to measure these values,
491
+ then use wall time. Wall time is measured using the gettimeofday kernel
492
+ method.</p>
493
+
494
+ <p>If you set the clock mode to <code>PROCESS_TIME</code>, then timings are
495
+ read using the clock method provided by the C runtime library. Note
496
+ though, these values are wall times on Windows and not process times like
497
+ on Linux. Wall time is measured using the GetLocalTime API.</p>
498
+
499
+ <p>If you use wall time, the results will be affected by other processes
500
+ running on your computer, network delays, disk access, etc. As result, for
501
+ the best results, try to make sure your computer is only performing your
502
+ profiling run and is otherwise quiescent.</p>
503
+
504
+ <h2 id="label-Multi-threaded+Applications">Multi-threaded Applications<span><a href="#label-Multi-threaded+Applications">&para;</a> <a href="#top">&uarr;</a></span></h2>
505
+
506
+ <p>Unfortunately, Ruby does not provide an internal API for detecting thread
507
+ context switches in 1.8. As a result, the timings ruby-prof reports for
508
+ each thread may be slightly inaccurate. In particular, this will happen
509
+ for newly spawned threads that go to sleep immediately (their first call).
510
+ For instance, if you use Ruby&#39;s timeout library to wait for 2 seconds,
511
+ the 2 seconds will be assigned to the foreground thread and not the newly
512
+ created background thread. These errors can largely be avoided if the
513
+ background thread performs any operation before going to sleep.</p>
514
+
515
+ <h2 id="label-Performance">Performance<span><a href="#label-Performance">&para;</a> <a href="#top">&uarr;</a></span></h2>
516
+
517
+ <p>Significant effort has been put into reducing ruby-prof&#39;s overhead as
518
+ much as possible. Our tests show that the overhead associated with
519
+ profiling code varies considerably with the code being profiled. Most
520
+ programs will run approximately twice as slow while highly recursive
521
+ programs (like the fibonacci series test) will run three times slower.</p>
522
+
523
+ <h2 id="label-License">License<span><a href="#label-License">&para;</a> <a href="#top">&uarr;</a></span></h2>
524
+
525
+ <p>See <a href="LICENSE.html">LICENSE</a> for license information.</p>
526
+
527
+ <h2 id="label-Development">Development<span><a href="#label-Development">&para;</a> <a href="#top">&uarr;</a></span></h2>
528
+
529
+ <p>Code is located at <a
530
+ href="https://github.com/ruby-prof/ruby-prof">github.com/ruby-prof/ruby-prof</a></p>
531
+
532
+ <p>Google group/mailing list: <a
533
+ href="http://groups.google.com/group/ruby-optimization">groups.google.com/group/ruby-optimization</a>
534
+ or open a github issue.</p>
535
+ </main>
536
+
537
+
538
+
539
+ <footer id="validator-badges" role="contentinfo">
540
+ <p><a href="http://validator.w3.org/check/referer">Validate</a>
541
+ <p>Generated by <a href="http://docs.seattlerb.org/rdoc/">RDoc</a> 4.2.0.
542
+ <p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
543
+ </footer>
544
+