google-perftools for ruby code
(c) 2009 Aman Gupta (tmm1)
=== Usage
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
Profile an existing ruby application without modifying it:
$ CPUPROFILE=/tmp/my_app_profile RUBYOPT="-r`gem which perftools | tail -1`" ruby my_app.rb
=== 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 http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html#pprof
=== 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
Simple require 'rubygems' profile
http://perftools-rb.rubyforge.org/examples/rubygems.gif
Comparing redis-rb with and without SystemTimer based socket timeouts
http://perftools-rb.rubyforge.org/examples/redis-rb.gif
http://perftools-rb.rubyforge.org/examples/redis-rb-notimeout.gif
Sinatra vs. Merb vs. Rails
http://perftools-rb.rubyforge.org/examples/sinatra.gif
http://perftools-rb.rubyforge.org/examples/merb.gif
http://perftools-rb.rubyforge.org/examples/rails.gif
C-level profile of EventMachine + epoll + Ruby threads
before http://timetobleed.com/6-line-eventmachine-bugfix-2x-faster-gc-1300-requestssec/
http://perftools-rb.rubyforge.org/examples/eventmachine-epoll+nothreads.gif
http://perftools-rb.rubyforge.org/examples/eventmachine-epoll+threads.gif
C-level profile of the ruby interpreter
12% time spent in re_match_exec because of excessive calls to rb_str_sub_bang by Date.parse
easily fixed by using the ThirdBase gem
http://perftools-rb.rubyforge.org/examples/ruby_interpreter.gif
=== Installation
Just install the gem, which will download, patch and compile google-perftools for you:
sudo gem install perftools.rb
Or use the dev gem from github:
gem install -s http://gems.github.com tmm1-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 port install graphviz # osx
sudo apt-get install graphviz # debian/ubuntu
=== Advantages over ruby-prof
Sampling profiler
perftools samples your process using setitimer() so it can be used in production with minimal overhead.
=== 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):
wget http://google-perftools.googlecode.com/files/google-perftools-1.3.tar.gz
tar zxvf google-perftools-1.3.tar.gz
cd google-perftools-1.3
./configure --prefix=/opt
make
sudo make install
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" } '
pprof `which ruby` --text /tmp/ruby_interpreter.profile
=== TODO
- Add support for heap profiling to find memory leaks (PerfTools::HeapProfiler)
- Allow both C and Ruby profiling
- Add setter for the sampling interval
- Add support for ruby 1.9
=== Resources
GoRuCo 2009 Lightning Talk on perftools.rb
http://goruco2009.confreaks.com/30-may-2009-18-35-rejectconf-various-presenters.html at 21:52
Ilya Grigorik's introduction to perftools.rb
http://www.igvita.com/2009/06/13/profiling-ruby-with-googles-perftools/
Google Perftools
http://code.google.com/p/google-perftools/
Analyzing profiles and interpreting different output formats
http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html#pprof