aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/testing/performance.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/testing/performance.rb')
-rw-r--r--activesupport/lib/active_support/testing/performance.rb87
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)