diff options
author | Emilio Tagua <miloops@gmail.com> | 2009-06-02 12:36:36 -0300 |
---|---|---|
committer | Emilio Tagua <miloops@gmail.com> | 2009-06-02 12:36:36 -0300 |
commit | fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90 (patch) | |
tree | 89f6b8eeae81ba9e9f3c43667b234b64a776e649 /tools/profile | |
parent | 5255a81b808c2c947d58df979e6436b1fe1d8157 (diff) | |
parent | 196f780e30fcece25e4d09c12f9b9f7374ebed29 (diff) | |
download | rails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.tar.gz rails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.tar.bz2 rails-fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90.zip |
Merge commit 'rails/master'
Conflicts:
activerecord/lib/active_record.rb
Diffstat (limited to 'tools/profile')
-rwxr-xr-x | tools/profile | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/tools/profile b/tools/profile new file mode 100755 index 0000000000..927467bc4e --- /dev/null +++ b/tools/profile @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +# Example: +# tools/profile_requires activesupport/lib/active_support.rb +# tools/profile_requires activeresource/examples/simple.rb +abort 'Use REE so you can profile memory and object allocation' unless GC.respond_to?(:enable_stats) + +ENV['NO_RELOAD'] ||= '1' +ENV['RAILS_ENV'] ||= 'development' + +GC.enable_stats +require 'rubygems' +Gem.source_index +require 'benchmark' + +module RequireProfiler + def require(file, *args) RequireProfiler.profile(file) { super } end + def load(file, *args) RequireProfiler.profile(file) { super } end + + @depth, @stats = 0, [] + class << self + attr_accessor :depth + attr_accessor :stats + + def profile(file) + stats << [file, depth] + self.depth += 1 + heap_before, objects_before = GC.allocated_size, ObjectSpace.allocated_objects + result = nil + elapsed = Benchmark.realtime { result = yield } + heap_after, objects_after = GC.allocated_size, ObjectSpace.allocated_objects + self.depth -= 1 + stats.pop if stats.last.first == file + stats << [file, depth, elapsed, heap_after - heap_before, objects_after - objects_before] if result + result + end + end +end + +GC.start +before = GC.allocated_size +before_rss = `ps -o rss= -p #{Process.pid}`.to_i +before_live_objects = ObjectSpace.live_objects + +path = ARGV.shift +if mode = ARGV.shift + require 'ruby-prof' + RubyProf.measure_mode = RubyProf.const_get(mode.upcase) + RubyProf.start +else + Object.instance_eval { include RequireProfiler } +end + +elapsed = Benchmark.realtime { require path } +results = RubyProf.stop if mode + +GC.start +after_live_objects = ObjectSpace.live_objects +after_rss = `ps -o rss= -p #{Process.pid}`.to_i +after = GC.allocated_size +usage = (after - before) / 1024.0 + +if mode + File.open("#{File.basename(path, '.rb')}.#{mode}.callgrind", 'w') do |out| + RubyProf::CallTreePrinter.new(results).print(out) + end +end + +RequireProfiler.stats.each do |file, depth, sec, bytes, objects| + if sec + puts "%10.2f KB %10d obj %8.1f ms %s%s" % [bytes / 1024.0, objects, sec * 1000, ' ' * depth, file] + else + puts "#{' ' * (42 + depth)}#{file}" + end +end +puts "%10.2f KB %10d obj %8.1f ms %d KB RSS" % [usage, after_live_objects - before_live_objects, elapsed * 1000, after_rss - before_rss] |