diff options
Diffstat (limited to 'activesupport/lib/active_support/testing/performance.rb')
-rw-r--r-- | activesupport/lib/active_support/testing/performance.rb | 87 |
1 files changed, 71 insertions, 16 deletions
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 5f2027eb3b..f996c40793 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -11,21 +11,21 @@ module ActiveSupport DEFAULTS = if benchmark = ARGV.include?('--benchmark') # HAX for rake test { :benchmark => true, - :runs => 10, + :runs => 4, :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time], :output => 'tmp/performance' } else { :benchmark => false, :runs => 1, - :min_percent => 0.02, + :min_percent => 0.01, :metrics => [:process_time, :memory, :objects], :formats => [:flat, :graph_html, :call_tree], :output => 'tmp/performance' } - end + end.freeze def self.included(base) - base.class_inheritable_hash :profile_options - base.profile_options = DEFAULTS.dup + base.superclass_delegating_accessor :profile_options + base.profile_options = DEFAULTS end def full_test_name @@ -39,12 +39,12 @@ module ActiveSupport @_result = result run_warmup - profile_options[:metrics].each do |metric_name| - if klass = Metrics[metric_name.to_sym] - run_profile(klass.new) - result.add_run - else - $stderr.puts '%20s: unsupported' % metric_name.to_s + if profile_options && metrics = profile_options[:metrics] + metrics.each do |metric_name| + if klass = Metrics[metric_name.to_sym] + run_profile(klass.new) + result.add_run + end end end @@ -72,13 +72,13 @@ module ActiveSupport protected def run_warmup - 5.times { GC.start } + GC.start time = Metrics::Time.new run_test(time, :benchmark) puts "%s (%s warmup)" % [full_test_name, time.format(time.total)] - 5.times { GC.start } + GC.start end def run_profile(metric) @@ -164,7 +164,14 @@ module ActiveSupport end class Profiler < Performer + def initialize(*args) + super + @supported = @metric.measure_mode rescue false + end + def run + return unless @supported + RubyProf.measure_mode = @metric.measure_mode RubyProf.start RubyProf.pause @@ -173,7 +180,17 @@ module ActiveSupport @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time } end + def report + if @supported + super + else + '%20s: unsupported' % @metric.name + end + end + def record + return unless @supported + klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact klasses.each do |klass| @@ -202,8 +219,7 @@ module ActiveSupport module Metrics def self.[](name) - klass = const_get(name.to_s.camelize) - klass if klass::Mode + const_get(name.to_s.camelize) rescue NameError nil end @@ -250,6 +266,16 @@ module ActiveSupport ensure GC.disable_stats end + elsif defined?(GC::Profiler) + def with_gc_stats + GC.start + GC.disable + GC::Profiler.enable + yield + ensure + GC::Profiler.disable + GC.enable + end else def with_gc_stats yield @@ -310,7 +336,7 @@ module ActiveSupport RubyProf.measure_memory / 1024.0 end - # Ruby 1.8 + adymo patch + # Ruby 1.8 + railsbench patch elsif GC.respond_to?(:allocated_size) def measure GC.allocated_size / 1024.0 @@ -322,11 +348,27 @@ module ActiveSupport GC.heap_info['heap_current_memory'] / 1024.0 end + # Ruby 1.9 with total_malloc_allocated_size patch + elsif GC.respond_to?(:malloc_total_allocated_size) + def measure + GC.total_malloc_allocated_size / 1024.0 + end + # Ruby 1.9 unpatched elsif GC.respond_to?(:malloc_allocated_size) def measure GC.malloc_allocated_size / 1024.0 end + + # Ruby 1.9 + GC profiler patch + elsif defined?(GC::Profiler) + def measure + GC.enable + GC.start + kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0 + GC.disable + kb + end end def format(measurement) @@ -341,10 +383,23 @@ module ActiveSupport def measure RubyProf.measure_allocations end + + # Ruby 1.8 + railsbench patch elsif ObjectSpace.respond_to?(:allocated_objects) def measure ObjectSpace.allocated_objects end + + # Ruby 1.9 + GC profiler patch + elsif defined?(GC::Profiler) + def measure + GC.enable + GC.start + last = GC::Profiler.data.last + count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS] + GC.disable + count + end end def format(measurement) |