diff options
Diffstat (limited to 'activesupport/lib/active_support/testing/performance.rb')
-rw-r--r-- | activesupport/lib/active_support/testing/performance.rb | 92 |
1 files changed, 80 insertions, 12 deletions
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 24936029a2..5f2027eb3b 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -12,13 +12,13 @@ module ActiveSupport if benchmark = ARGV.include?('--benchmark') # HAX for rake test { :benchmark => true, :runs => 10, - :metrics => [:process_time, :memory, :objects], + :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time], :output => 'tmp/performance' } else { :benchmark => false, :runs => 1, :min_percent => 0.02, - :metrics => [:wall_time, :memory, :objects], + :metrics => [:process_time, :memory, :objects], :formats => [:flat, :graph_html, :call_tree], :output => 'tmp/performance' } end @@ -44,7 +44,7 @@ module ActiveSupport run_profile(klass.new) result.add_run else - $stderr.puts "Skipping unknown metric #{metric_name.inspect}. Expected :process_time, :wall_time, :cpu_time, :memory, or :objects." + $stderr.puts '%20s: unsupported' % metric_name.to_s end end @@ -72,9 +72,13 @@ module ActiveSupport protected def run_warmup + 5.times { 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 } end def run_profile(metric) @@ -95,8 +99,13 @@ module ActiveSupport def report rate = @total / profile_options[:runs] - '%20s: %s/run' % [@metric.name, @metric.format(rate)] + '%20s: %s' % [@metric.name, @metric.format(rate)] end + + protected + def output_filename + "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}" + end end class Benchmarker < Performer @@ -107,9 +116,9 @@ module ActiveSupport def record avg = @metric.total / profile_options[:runs].to_i - data = [full_test_name, @metric.name, avg, Time.now.utc.xmlschema] * ',' + now = Time.now.utc.xmlschema with_output_file do |file| - file.puts "#{data},#{environment}" + file.puts "#{avg},#{now},#{environment}" end end @@ -134,10 +143,10 @@ module ActiveSupport end protected - HEADER = 'test,metric,measurement,created_at,app,rails,ruby,platform' + HEADER = 'measurement,created_at,app,rails,ruby,platform' def with_output_file - fname = "#{profile_options[:output]}/benchmarks.csv" + fname = output_filename if new = !File.exist?(fname) FileUtils.mkdir_p(File.dirname(fname)) @@ -148,6 +157,10 @@ module ActiveSupport yield file end end + + def output_filename + "#{super}.csv" + end end class Profiler < Performer @@ -183,7 +196,7 @@ module ActiveSupport else printer_class.name.sub(/Printer$/, '').underscore end - "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}_#{suffix}" + "#{super()}_#{suffix}" end end @@ -210,6 +223,10 @@ module ActiveSupport self.class::Mode end + def measure + 0 + end + def benchmark with_gc_stats do before = measure @@ -271,7 +288,7 @@ module ActiveSupport end class CpuTime < Time - Mode = RubyProf::CPU_TIME + Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME) def initialize(*args) # FIXME: yeah my CPU is 2.33 GHz @@ -285,16 +302,27 @@ module ActiveSupport end class Memory < Base - Mode = RubyProf::MEMORY + Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY) + # ruby-prof wrapper if RubyProf.respond_to?(:measure_memory) def measure RubyProf.measure_memory / 1024.0 end + + # Ruby 1.8 + adymo patch elsif GC.respond_to?(:allocated_size) def measure GC.allocated_size / 1024.0 end + + # Ruby 1.8 + lloyd patch + elsif GC.respond_to?(:heap_info) + def measure + GC.heap_info['heap_current_memory'] / 1024.0 + end + + # Ruby 1.9 unpatched elsif GC.respond_to?(:malloc_allocated_size) def measure GC.malloc_allocated_size / 1024.0 @@ -307,7 +335,7 @@ module ActiveSupport end class Objects < Base - Mode = RubyProf::ALLOCATIONS + Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS) if RubyProf.respond_to?(:measure_allocations) def measure @@ -323,6 +351,46 @@ module ActiveSupport measurement.to_i.to_s end end + + class GcRuns < Base + Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS) + + if RubyProf.respond_to?(:measure_gc_runs) + def measure + RubyProf.measure_gc_runs + end + elsif GC.respond_to?(:collections) + def measure + GC.collections + end + elsif GC.respond_to?(:heap_info) + def measure + GC.heap_info['num_gc_passes'] + end + end + + def format(measurement) + measurement.to_i.to_s + end + end + + class GcTime < Base + Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME) + + if RubyProf.respond_to?(:measure_gc_time) + def measure + RubyProf.measure_gc_time + end + elsif GC.respond_to?(:time) + def measure + GC.time + end + end + + def format(measurement) + '%d ms' % (measurement / 1000) + end + end end end end |