I'm new to Ruby profiling, and it seems like ruby-prof
is a popular choice. I just installed the gem and invoked my program:
ruby-prof ./my-prog.rb
However, the output is incredibly verbose, because profiling data for all the Ruby core and standard library methods, and other gems are included. For example, the top three lines are:
8.79 0.011 0.010 0.000 0.001 3343 *String#%
7.28 0.078 0.009 0.000 0.069 2068 *Array#each
4.93 0.038 0.006 0.000 0.032 1098 *Array#map
That's not remotely useful information for me, since I already know that my program deals with Strings and Arrays a lot, and presumably those classes have already had the hell optimised out of them. I only care about the hotspots in my code.
I tried some of the other printer modes, e.g. -p graph_html
and -p call_stack
, but they all have the same problem.
I see that ruby-prof
supports some method elimination and simplification:
-x, --exclude regexp exclude methods by regexp (see method elimination)
-X, --exclude-file file exclude methods by regexp listed in file (see method elimination)
--exclude-common-cycles make common iterators like Integer#times appear inlined
--exclude-common-callbacks make common callbacks invocations like Integer#times appear
but there doesn't seem to be any obvious way to get what I really want, which is profiling data for my code only, i.e. with time elapsed inside code from Ruby core / stdlib, and other gems only being counted as time elapsed inside my code.
Once I can see that my code has a method foo
which is a performance bottleneck due to being called thousands of times and not performing well, then and only do I want to see the breakdown of time elapsed between my code and core/library code called within that particular method.
I can't understand why this isn't a standard feature, since I would expect that it's what everyone wants to do: profile your own code first, and then once you've run out of things to optimize, potentially start optimizing the gems you use and maybe even Ruby core / stdlib. What am I missing?
You may want to profile and benchmark via tests. Minitest allows for this in their testing framework. That way you can concentrate on specific behaviors to get your timings.
Available in Ruby 2.0 or as a Gem for Ruby 1.9 and lower.
As far as profiling in the same way,
require 'profile'
and use it for those same tests.This blog post details how to do this, I don't believe it has changed greatly.