perftools.rb

google-perftools for ruby code
(c) 2010 Aman Gupta (tmm1)
http://www.ruby-lang.org/en/LICENSE.txt

Usage (in a webapp)

Use rack-perftools_profiler:

require 'rack/perftools_profiler'
config.middleware.use ::Rack::PerftoolsProfiler, :default_printer => 'gif'

Simply add profile=true to profile a request:

curl -o 10_requests_to_homepage.gif "http://localhost:3000/homepage?profile=true&times=10"

Usage (from Ruby)

Run the profiler with a block:

require 'perftools'
PerfTools::CpuProfiler.start("/tmp/add_numbers_profile") do
  5_000_000.times{ 1+2+3+4+5 }
end

Start and stop the profiler manually:

require 'perftools'
PerfTools::CpuProfiler.start("/tmp/add_numbers_profile")
5_000_000.times{ 1+2+3+4+5 }
PerfTools::CpuProfiler.stop

Usage (externally)

Profile an existing ruby application without modifying it:

$ CPUPROFILE=/tmp/my_app_profile \
  RUBYOPT="-r`gem which perftools | tail -1`" \
  ruby my_app.rb

Profiler Modes

The profiler can be run in one of many modes, set via an environment variable before the library is loaded:

The sampling interval of the profiler can be adjusted to collect more (for better profile detail) or fewer samples (for lower overhead):

Reporting

pprof.rb --text /tmp/add_numbers_profile

pprof.rb --pdf /tmp/add_numbers_profile > /tmp/add_numbers_profile.pdf

pprof.rb --gif /tmp/add_numbers_profile > /tmp/add_numbers_profile.gif

pprof.rb --callgrind /tmp/add_numbers_profile > /tmp/add_numbers_profile.grind
kcachegrind /tmp/add_numbers_profile.grind

pprof.rb --gif --focus=Integer /tmp/add_numbers_profile > /tmp/add_numbers_custom.gif

pprof.rb --text --ignore=Gem /tmp/my_app_profile

For more options, see pprof documentation

Examples

pprof.rb --text

Total: 1735 samples
    1487  85.7%  85.7%     1735 100.0% Integer#times
     248  14.3% 100.0%      248  14.3% Fixnum#+

pprof.rb --gif

Installation

Just install the gem, which will download, patch and compile google-perftools for you:

sudo gem install perftools.rb

Or build your own gem:

git clone git://github.com/tmm1/perftools.rb
cd perftools.rb
gem build perftools.rb.gemspec
gem install perftools.rb

You'll also need graphviz to generate call graphs using dot:

sudo brew    install graphviz ghostscript # osx
sudo apt-get install graphviz ps2pdf      # debian/ubuntu

If graphviz fails to build on OSX Lion, you may need to recompile libgd, see here

Advantages over ruby-prof

Profiling the Ruby VM and C extensions

To profile C code, download and build an unpatched perftools (libunwind or ./configure --enable-frame-pointers required on x86_64).

Download:

wget http://google-perftools.googlecode.com/files/google-perftools-1.6.tar.gz
tar zxvf google-perftools-1.6.tar.gz
cd google-perftools-1.6

Compile:

./configure --prefix=/opt
make
sudo make install

Profile:

export LD_PRELOAD=/opt/lib/libprofiler.so                 # for linux
export DYLD_INSERT_LIBRARIES=/opt/lib/libprofiler.dylib   # for osx
CPUPROFILE=/tmp/ruby_interpreter.profile ruby -e' 5_000_000.times{ "hello world" } '

Report:

pprof `which ruby` --text /tmp/ruby_interpreter.profile

TODO

Resources