Profiling Ruby on Rails App

I think everyone is enjoy ruby's programming, the meta programming is really efficiently way. But sometime we meet our function or app have a poor performance.

Guess what, my first through was, ruby is f**k too slow.. , but my second through was, how can I figure out where is slow, rather than switch some other language?

So let's start some profiling to figure it out.

add this in your Gemfile or gem install it.

gem 'ruby-prof', :git => 'git://github.com/ruby-prof/ruby-prof.git', :group => [:development, :test]

Add this function in your ApplicationController.rb

 def profile(prefix = "profile")
    result = RubyProf.profile { yield }

    dir = File.join(Rails.root, "tmp", "performance", params[:controller].parameterize)
    FileUtils.mkdir_p(dir)
    file = File.join(dir, "callgrind.%s.%s.%s" % [prefix.parameterize, params[:action].parameterize, Time.now.to_s.parameterize] )
    open(file, "w") {|f| RubyProf::CallTreePrinter.new(result).print(f, :min_percent => 1) }
  end

  helper_method :profile

You can put what you want profile in this block, and it will generate callgrind file under your tmp/performance/[controller-name] folder.

If you're under mac, you can install this tool to check the function profiling:

brew install qcachegrind

other platform have some equal tools like, kcachegrind under linux.

you will got the profile result like this picture.

屏幕快照 2014-06-12 下午12.53.38

Hope this will help you figure out which part is cause the performance issue.

And my other little trick is, like the :profile helper, I add a simple timer helper:

 def timer(tag = "default")

   t1 = Time.now
   yield
   t2 = Time.now
   
   msecs = (t2 - t1) * 1000.0
   logger.info "Time in profile #{tag} #{msecs.to_i} ms"

 end

 helper_method :timer

Together with code block, you can get each part 's timer profile like below:

timer("total") do 

  timer("func1") do 
  function1
  end

  function2 

  timer("loop") do
      some_array.each { function }
  end

end

Seems too naive, but this simple method can be more helpful than other complex tools.