<p>What is the best way to profile a controller action in Ruby on Rails. Currently I am using the brute-force method of throwing in <code>puts Time.now</code> calls between what I think will be a bottleneck. But that feels really, really dirty. There has got to be a better way.</p>

[{'answer_id': 31359, 'author': 'Chris Bunch', 'author_id': 422, 'author_profile': 'https://Stackoverflow.com/users/422', 'pm_score': 3, 'selected': False, 'text': '<p>Use the Benchmark standard library and the various tests available in Rails (unit, functional, integration). Here\'s an example:</p>\n\n<pre><code>def test_do_something\n  elapsed_time = Benchmark.realtime do\n    100.downto(1) do |index|\n      # do something here\n    end\n  end\n  assert elapsed_time &lt; SOME_LIMIT\nend\n</code></pre>\n\n<p>So here we just do something 100 times, time it via the Benchmark library, and ensure that it took less than SOME_LIMIT amount of time.</p>\n\n<p>You also may find these links useful: The <a href="http://www.ruby-doc.org/stdlib/libdoc/benchmark/rdoc/classes/Benchmark.html#M000011" rel="noreferrer">Benchmark.realtime reference</a> and the <a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html" rel="noreferrer">Test::Unit reference</a>. Also, if you\'re into the \'book reading\' thing, I picked up the idea for the example from <a href="http://www.pragprog.com/titles/rails2/agile-web-development-with-rails" rel="noreferrer">Agile Web Development with Rails</a>, which talks all about the different testing types and a little on performance testing.</p>\n'}, {'answer_id': 33043, 'author': 'Stuart', 'author_id': 3162, 'author_profile': 'https://Stackoverflow.com/users/3162', 'pm_score': 3, 'selected': False, 'text': '<p>There\'s a Railscast on profiling that\'s well worth watching</p>\n\n<p><a href="http://railscasts.com/episodes/98-request-profiling" rel="noreferrer">http://railscasts.com/episodes/98-request-profiling</a></p>\n'}, {'answer_id': 33077, 'author': 'John Topley', 'author_id': 1450, 'author_profile': 'https://Stackoverflow.com/users/1450', 'pm_score': 1, 'selected': False, 'text': '<p>You might want to give the <a href="http://www.fiveruns.com/products/tuneup" rel="nofollow noreferrer">FiveRuns TuneUp</a> service a try, as it\'s really rather impressive. <em>Disclaimer: I\'m not associated with FiveRuns in any way, I\'ve just tried this service out.</em></p>\n\n<p>TuneUp is a free service whereby you download a plugin and when you run your application it injects a panel at the top of the screen that can be expanded to display detailed performance metrics.</p>\n\n<p>It gives you some nice graphs, including one that shows what proportion of time is spent in the Model, View and Controller. You can even drill right down to see the individual SQL queries that ActiveRecord is executing if you need to and it can show you the underlying database schema with another click.</p>\n\n<p>Finally, you can optionally upload your profiling data to the FiveRuns site for community performance analysis and advice.</p>\n'}, {'answer_id': 9042581, 'author': 'Rob Davis', 'author_id': 461347, 'author_profile': 'https://Stackoverflow.com/users/461347', 'pm_score': 5, 'selected': False, 'text': '<p>I picked up this technique a while back and have found it quite handy.</p>\n\n<p>When it\'s in place, you can add <code>?profile=true</code> to any URL that hits a controller. Your action will run as usual, but instead of delivering the rendered page to the browser, it\'ll send a detailed, nicely formatted ruby-prof page that shows where your action spent its time.</p>\n\n<p>First, add ruby-prof to your Gemfile, probably in the development group:</p>\n\n<pre><code>group :development do\n    gem "ruby-prof"\nend\n</code></pre>\n\n<p>Then add an <a href="http://guides.rubyonrails.org/action_controller_overview.html#after-filters-and-around-filters" rel="nofollow noreferrer">around filter</a> to your ApplicationController:</p>\n\n<pre><code>around_action :performance_profile if Rails.env == \'development\'\n\ndef performance_profile\n  if params[:profile] &amp;&amp; result = RubyProf.profile { yield }\n\n    out = StringIO.new\n    RubyProf::GraphHtmlPrinter.new(result).print out, :min_percent =&gt; 0\n    self.response_body = out.string\n\n  else\n    yield\n  end\nend\n</code></pre>\n\n<p>Reading the ruby-prof output is a bit of an art, but I\'ll leave that as an exercise.</p>\n\n<p><strong>Additional note by ScottJShea:</strong>\nIf you want to change the measurement type place this:</p>\n\n<p><code>RubyProf.measure_mode = RubyProf::GC_TIME #example</code></p>\n\n<p>Before the <code>if</code> in the profile method of the application controller. You can find a list of the available measurements at the <a href="https://github.com/ruby-prof/ruby-prof#measurements" rel="nofollow noreferrer">ruby-prof page</a>. As of this writing the <code>memory</code> and <code>allocations</code> data streams seem to be corrupted (<a href="https://github.com/ruby-prof/ruby-prof/issues/86" rel="nofollow noreferrer">see defect</a>).</p>\n'}, {'answer_id': 36879670, 'author': 'Minqi Pan', 'author_id': 740014, 'author_profile': 'https://Stackoverflow.com/users/740014', 'pm_score': -1, 'selected': False, 'text': "<p>This works in Rails 4.2.6:</p>\n\n<pre><code>    o=OpenStruct.new(logger: Rails.logger)\n    o.extend ActiveSupport::Benchmarkable\n    o.benchmark 'name' do\n      # ... your code ...\n    end\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/31320', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/757/']