<?xml version="1.0" encoding="UTF-8"?>
<snippet>
  <account-id type="integer">2</account-id>
  <body>h2. Installing ruby-prof

First install &quot;ruby-prof&quot;:http://ruby-prof.rubyforge.org/:

&lt;code&gt;
git clone git://github.com/jeremy/ruby-prof.git
cd ruby-prof/
rake gem
sudo gem install pkg/ruby-prof-0.6.1.gem
&lt;/code&gt;

Note that version 0.6.0 doesn't work, at least not with Rails 2.1.1. With 0.6.0 I got this message:

&lt;code&gt;
`gem install ruby-prof` to use the profiler
&lt;/code&gt;

h2. Setting up a new environment for profiling

Create *config/environments/profiling.rb*:

&lt;code&gt;
config.cache_classes = true
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching             = true
config.action_view.cache_template_loading            = true

#config.log_level = :debug
&lt;/code&gt;

Add the new environment to database.yml. You might want to reuse the development database.

h2. Creating a profiling script

Next we'll create a script that simply fetches the homepage, save the following code in *profiling/homepage.rb*:

&lt;code&gt;
get '/'
say &quot;GET / =&gt; #{path}&quot;
&lt;/code&gt;

h2. Run the script

Now run the script 100 times:

&lt;code&gt;
RAILS_ENV=profiling ./script/performance/request -n 100 profiling/homepage.rb
&lt;/code&gt;

h2. Profiling plain Ruby applications

You can also profile a block of code by &quot;calling RubyProf from your code&quot;:http://ruby-prof.rubyforge.org/:

&lt;code&gt;
require 'ruby-prof'

# Profile the code
RubyProf.start
...
[code to profile]
...
results = RubyProf.stop

File.open &quot;#{RAILS_ROOT}/tmp/profile-graph.html&quot;, 'w' do |file|
  RubyProf::GraphHtmlPrinter.new(results).print(file)
end

File.open &quot;#{RAILS_ROOT}/tmp/profile-flat.txt&quot;, 'w' do |file|
  RubyProf::FlatPrinter.new(results).print(file)
end

File.open &quot;#{RAILS_ROOT}/tmp/profile-tree.prof&quot;, 'w' do |file|
  RubyProf::CallTreePrinter.new(results).print(file)
end
&lt;/code&gt;

h2. Analyzing results

I prefer to use the RubyProf::CallTreePrinter to output data that &quot;kcachegrind&quot;:http://kcachegrind.sourceforge.net/ can read. The HTML and text data is difficult to read so kcachegrind will definitely make your life easier.

On OSX you can install kcachegrind with &quot;Fink&quot;:http://www.finkproject.org/download/index.php?phpLang=en (or DarwinPorts):

&lt;code&gt;
sudo apt-get update ; sudo apt-get install fink
sudo apt-get install kcachegrind
&lt;/code&gt;

There's also WinCacheGrind and MacCacheGrind, but I haven't tried those.</body>
  <comments-count type="integer">0</comments-count>
  <created-at type="datetime">2008-09-26T22:25:54+03:00</created-at>
  <id type="integer">255</id>
  <language-id type="integer">124</language-id>
  <rendered-body>&lt;h2&gt;Installing ruby-prof&lt;/h2&gt;
&lt;p&gt;First install &lt;a href=&quot;http://ruby-prof.rubyforge.org/&quot;&gt;ruby-prof&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; git clone git&lt;span class=&quot;UserDefinedConstant&quot;&gt;&lt;span class=&quot;UserDefinedConstant&quot;&gt;:&lt;/span&gt;/&lt;/span&gt;&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;github.&lt;span class=&quot;FunctionName&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;jeremy&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;ruby&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;prof.&lt;span class=&quot;FunctionName&quot;&gt;git&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   2 &lt;/span&gt; cd ruby&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;prof&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   3 &lt;/span&gt; rake gem
&lt;span class=&quot;line-numbers&quot;&gt;   4 &lt;/span&gt; sudo gem install pkg&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;ruby&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;prof&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;Number&quot;&gt;0.6&lt;/span&gt;.&lt;span class=&quot;Number&quot;&gt;1&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;gem&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Note that version 0.6.0 doesn&amp;#8217;t work, at least not with Rails 2.1.1. With 0.6.0 I got this message:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;gem install ruby-prof&lt;span class=&quot;String&quot;&gt;`&lt;/span&gt;&lt;/span&gt; to use the profiler
&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Setting up a new environment for profiling&lt;/h2&gt;
&lt;p&gt;Create &lt;strong&gt;config/environments/profiling.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; config.&lt;span class=&quot;FunctionName&quot;&gt;cache_classes&lt;/span&gt; &lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;BuiltInConstant&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   2 &lt;/span&gt; config.&lt;span class=&quot;FunctionName&quot;&gt;action_controller&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;consider_all_requests_local&lt;/span&gt; &lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;BuiltInConstant&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   3 &lt;/span&gt; config.&lt;span class=&quot;FunctionName&quot;&gt;action_controller&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;perform_caching&lt;/span&gt;             &lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;BuiltInConstant&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   4 &lt;/span&gt; config.&lt;span class=&quot;FunctionName&quot;&gt;action_view&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;cache_template_loading&lt;/span&gt;            &lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;BuiltInConstant&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   5 &lt;/span&gt; 
&lt;span class=&quot;line-numbers&quot;&gt;   6 &lt;/span&gt; &lt;span class=&quot;LineComment&quot;&gt;&lt;span class=&quot;LineComment&quot;&gt;#&lt;/span&gt;config.log_level = :debug&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Add the new environment to database.yml. You might want to reuse the development database.&lt;/p&gt;
&lt;h2&gt;Creating a profiling script&lt;/h2&gt;
&lt;p&gt;Next we&amp;#8217;ll create a script that simply fetches the homepage, save the following code in &lt;strong&gt;profiling/homepage.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; get &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;/&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   2 &lt;/span&gt; say &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;GET / =&amp;gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;#{&lt;/span&gt;path&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Run the script&lt;/h2&gt;
&lt;p&gt;Now run the script 100 times:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; &lt;span class=&quot;Variable&quot;&gt;RAILS_ENV&lt;/span&gt;&lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt;profiling .&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;script&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;performance&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;request &lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;n &lt;span class=&quot;Number&quot;&gt;100&lt;/span&gt; profiling&lt;span class=&quot;Operator&quot;&gt;/&lt;/span&gt;homepage.&lt;span class=&quot;FunctionName&quot;&gt;rb&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Profiling plain Ruby applications&lt;/h2&gt;
&lt;p&gt;You can also profile a block of code by &lt;a href=&quot;http://ruby-prof.rubyforge.org/&quot;&gt;calling RubyProf from your code&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;ruby-prof&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   2 &lt;/span&gt; 
&lt;span class=&quot;line-numbers&quot;&gt;   3 &lt;/span&gt; &lt;span class=&quot;LineComment&quot;&gt;&lt;span class=&quot;LineComment&quot;&gt;#&lt;/span&gt; Profile the code&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   4 &lt;/span&gt; &lt;span class=&quot;LibraryClassType&quot;&gt;RubyProf&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;start&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   5 &lt;/span&gt; ...
&lt;span class=&quot;line-numbers&quot;&gt;   6 &lt;/span&gt; [code to profile]
&lt;span class=&quot;line-numbers&quot;&gt;   7 &lt;/span&gt; ...
&lt;span class=&quot;line-numbers&quot;&gt;   8 &lt;/span&gt; results &lt;span class=&quot;Operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;LibraryClassType&quot;&gt;RubyProf&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;stop&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;   9 &lt;/span&gt; 
&lt;span class=&quot;line-numbers&quot;&gt;  10 &lt;/span&gt; &lt;span class=&quot;LibraryClassType&quot;&gt;File&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;RAILS_ROOT&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;/tmp/profile-graph.html&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;w&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;file&lt;/span&gt;|
&lt;span class=&quot;line-numbers&quot;&gt;  11 &lt;/span&gt;   &lt;span class=&quot;LibraryClassType&quot;&gt;RubyProf&lt;/span&gt;::&lt;span class=&quot;FunctionName&quot;&gt;GraphHtmlPrinter&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;new&lt;/span&gt;(results).&lt;span class=&quot;FunctionName&quot;&gt;print&lt;/span&gt;(file)
&lt;span class=&quot;line-numbers&quot;&gt;  12 &lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  13 &lt;/span&gt; 
&lt;span class=&quot;line-numbers&quot;&gt;  14 &lt;/span&gt; &lt;span class=&quot;LibraryClassType&quot;&gt;File&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;RAILS_ROOT&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;/tmp/profile-flat.txt&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;w&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;file&lt;/span&gt;|
&lt;span class=&quot;line-numbers&quot;&gt;  15 &lt;/span&gt;   &lt;span class=&quot;LibraryClassType&quot;&gt;RubyProf&lt;/span&gt;::&lt;span class=&quot;FunctionName&quot;&gt;FlatPrinter&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;new&lt;/span&gt;(results).&lt;span class=&quot;FunctionName&quot;&gt;print&lt;/span&gt;(file)
&lt;span class=&quot;line-numbers&quot;&gt;  16 &lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;line-numbers&quot;&gt;  17 &lt;/span&gt; 
&lt;span class=&quot;line-numbers&quot;&gt;  18 &lt;/span&gt; &lt;span class=&quot;LibraryClassType&quot;&gt;File&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;Variable&quot;&gt;RAILS_ROOT&lt;/span&gt;&lt;span class=&quot;String&quot;&gt;}&lt;/span&gt;&lt;/span&gt;/tmp/profile-tree.prof&lt;span class=&quot;String&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;w&lt;span class=&quot;String&quot;&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;do &lt;/span&gt;|&lt;span class=&quot;Variable&quot;&gt;file&lt;/span&gt;|
&lt;span class=&quot;line-numbers&quot;&gt;  19 &lt;/span&gt;   &lt;span class=&quot;LibraryClassType&quot;&gt;RubyProf&lt;/span&gt;::&lt;span class=&quot;FunctionName&quot;&gt;CallTreePrinter&lt;/span&gt;.&lt;span class=&quot;FunctionName&quot;&gt;new&lt;/span&gt;(results).&lt;span class=&quot;FunctionName&quot;&gt;print&lt;/span&gt;(file)
&lt;span class=&quot;line-numbers&quot;&gt;  20 &lt;/span&gt; &lt;span class=&quot;Keyword&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Analyzing results&lt;/h2&gt;
&lt;p&gt;I prefer to use the RubyProf::CallTreePrinter to output data that &lt;a href=&quot;http://kcachegrind.sourceforge.net/&quot;&gt;kcachegrind&lt;/a&gt; can read. The &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and text data is difficult to read so kcachegrind will definitely make your life easier.&lt;/p&gt;
&lt;p&gt;On &lt;span class=&quot;caps&quot;&gt;OSX&lt;/span&gt; you can install kcachegrind with &lt;a href=&quot;http://www.finkproject.org/download/index.php?phpLang=en&quot;&gt;Fink&lt;/a&gt; (or DarwinPorts):&lt;/p&gt;
&lt;p&gt;&lt;pre class=&quot;active4d&quot;&gt;&lt;span class=&quot;line-numbers&quot;&gt;   1 &lt;/span&gt; sudo apt&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;get update ; sudo apt&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;get install fink
&lt;span class=&quot;line-numbers&quot;&gt;   2 &lt;/span&gt; sudo apt&lt;span class=&quot;Operator&quot;&gt;-&lt;/span&gt;get install kcachegrind
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s also WinCacheGrind and MacCacheGrind, but I haven&amp;#8217;t tried those.&lt;/p&gt;</rendered-body>
  <title>How to profile your Rails and Ruby applications with ruby-prof</title>
  <updated-at type="datetime">2008-12-13T12:52:21+02:00</updated-at>
</snippet>
