From d73f2ff4341effc1232abbf4c4be0f034267508a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 27 May 2009 01:11:33 -0500 Subject: Rename tools/profile_requires -> tools/profile since we do both require and ruby-prof profiling. --- tools/profile | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/profile_requires | 75 -------------------------------------------------- 2 files changed, 75 insertions(+), 75 deletions(-) create mode 100755 tools/profile delete mode 100755 tools/profile_requires (limited to 'tools') 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] diff --git a/tools/profile_requires b/tools/profile_requires deleted file mode 100755 index 927467bc4e..0000000000 --- a/tools/profile_requires +++ /dev/null @@ -1,75 +0,0 @@ -#!/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] -- cgit v1.2.3