activesupport 3.0.20 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. data/CHANGELOG +24 -28
  2. data/README.rdoc +2 -2
  3. data/lib/active_support/backtrace_cleaner.rb +17 -12
  4. data/lib/active_support/buffered_logger.rb +7 -9
  5. data/lib/active_support/cache/file_store.rb +4 -3
  6. data/lib/active_support/cache/mem_cache_store.rb +10 -2
  7. data/lib/active_support/cache/strategy/local_cache.rb +28 -23
  8. data/lib/active_support/cache.rb +11 -14
  9. data/lib/active_support/callbacks.rb +195 -175
  10. data/lib/active_support/concern.rb +105 -35
  11. data/lib/active_support/configurable.rb +50 -8
  12. data/lib/active_support/core_ext/array/access.rb +2 -2
  13. data/lib/active_support/core_ext/array/conversions.rb +2 -2
  14. data/lib/active_support/core_ext/array/random_access.rb +10 -7
  15. data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
  16. data/lib/active_support/core_ext/array/wrap.rb +1 -1
  17. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
  18. data/lib/active_support/core_ext/class/attribute.rb +15 -1
  19. data/lib/active_support/core_ext/class/inheritable_attributes.rb +10 -86
  20. data/lib/active_support/core_ext/class/subclasses.rb +20 -34
  21. data/lib/active_support/core_ext/date/calculations.rb +17 -5
  22. data/lib/active_support/core_ext/date/conversions.rb +9 -2
  23. data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
  24. data/lib/active_support/core_ext/date_time/conversions.rb +9 -9
  25. data/lib/active_support/core_ext/date_time/zones.rb +1 -1
  26. data/lib/active_support/core_ext/enumerable.rb +3 -6
  27. data/lib/active_support/core_ext/float/rounding.rb +1 -1
  28. data/lib/active_support/core_ext/hash/conversions.rb +22 -34
  29. data/lib/active_support/core_ext/hash/deep_dup.rb +11 -0
  30. data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
  31. data/lib/active_support/core_ext/hash/keys.rb +6 -4
  32. data/lib/active_support/core_ext/hash/reverse_merge.rb +9 -14
  33. data/lib/active_support/core_ext/hash/slice.rb +3 -1
  34. data/lib/active_support/core_ext/hash.rb +1 -0
  35. data/lib/active_support/core_ext/integer/inflections.rb +7 -4
  36. data/lib/active_support/core_ext/kernel/reporting.rb +31 -0
  37. data/lib/active_support/core_ext/kernel/requires.rb +2 -0
  38. data/lib/active_support/core_ext/logger.rb +11 -38
  39. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +12 -12
  40. data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
  41. data/lib/active_support/core_ext/module/delegation.rb +1 -5
  42. data/lib/active_support/core_ext/module/remove_method.rb +7 -2
  43. data/lib/active_support/core_ext/numeric/time.rb +2 -0
  44. data/lib/active_support/core_ext/object/blank.rb +45 -12
  45. data/lib/active_support/core_ext/object/duplicable.rb +50 -9
  46. data/lib/active_support/core_ext/object/inclusion.rb +15 -0
  47. data/lib/active_support/core_ext/object/instance_variables.rb +1 -35
  48. data/lib/active_support/core_ext/object/to_param.rb +13 -8
  49. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  50. data/lib/active_support/core_ext/object/try.rb +29 -10
  51. data/lib/active_support/core_ext/object/with_options.rb +25 -8
  52. data/lib/active_support/core_ext/object.rb +1 -1
  53. data/lib/active_support/core_ext/range/cover.rb +3 -0
  54. data/lib/active_support/core_ext/range.rb +1 -0
  55. data/lib/active_support/core_ext/string/behavior.rb +1 -2
  56. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  57. data/lib/active_support/core_ext/string/exclude.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +3 -3
  59. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  60. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  61. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  62. data/lib/active_support/core_ext/string/output_safety.rb +45 -62
  63. data/lib/active_support/core_ext/string.rb +1 -0
  64. data/lib/active_support/core_ext/time/calculations.rb +19 -16
  65. data/lib/active_support/core_ext/time/conversions.rb +2 -24
  66. data/lib/active_support/core_ext/time/zones.rb +32 -21
  67. data/lib/active_support/core_ext/uri.rb +8 -0
  68. data/lib/active_support/dependencies.rb +74 -28
  69. data/lib/active_support/deprecation/behaviors.rb +7 -0
  70. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  71. data/lib/active_support/deprecation/reporting.rb +4 -0
  72. data/lib/active_support/deprecation.rb +2 -2
  73. data/lib/active_support/descendants_tracker.rb +9 -7
  74. data/lib/active_support/duration.rb +5 -0
  75. data/lib/active_support/file_update_checker.rb +1 -1
  76. data/lib/active_support/file_watcher.rb +36 -0
  77. data/lib/active_support/hash_with_indifferent_access.rb +20 -8
  78. data/lib/active_support/i18n.rb +0 -1
  79. data/lib/active_support/i18n_railtie.rb +2 -2
  80. data/lib/active_support/inflections.rb +1 -0
  81. data/lib/active_support/inflector/inflections.rb +1 -1
  82. data/lib/active_support/inflector/methods.rb +5 -3
  83. data/lib/active_support/json/decoding.rb +37 -23
  84. data/lib/active_support/json/encoding.rb +12 -4
  85. data/lib/active_support/lazy_load_hooks.rb +7 -7
  86. data/lib/active_support/log_subscriber/test_helper.rb +5 -3
  87. data/lib/active_support/log_subscriber.rb +6 -6
  88. data/lib/active_support/message_encryptor.rb +1 -1
  89. data/lib/active_support/message_verifier.rb +1 -1
  90. data/lib/active_support/multibyte/chars.rb +5 -5
  91. data/lib/active_support/multibyte/unicode.rb +2 -1
  92. data/lib/active_support/notifications/fanout.rb +3 -3
  93. data/lib/active_support/notifications/instrumenter.rb +1 -1
  94. data/lib/active_support/notifications.rb +9 -10
  95. data/lib/active_support/ordered_hash.rb +23 -2
  96. data/lib/active_support/ordered_options.rb +37 -3
  97. data/lib/active_support/railtie.rb +1 -1
  98. data/lib/active_support/rescuable.rb +1 -0
  99. data/lib/active_support/secure_random.rb +3 -196
  100. data/lib/active_support/test_case.rb +2 -10
  101. data/lib/active_support/testing/assertions.rb +20 -7
  102. data/lib/active_support/testing/mochaing.rb +7 -0
  103. data/lib/active_support/testing/pending.rb +27 -23
  104. data/lib/active_support/testing/performance/jruby.rb +115 -0
  105. data/lib/active_support/testing/performance/rubinius.rb +113 -0
  106. data/lib/active_support/testing/performance/ruby/mri.rb +57 -0
  107. data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
  108. data/lib/active_support/testing/performance/ruby.rb +152 -0
  109. data/lib/active_support/testing/performance.rb +214 -322
  110. data/lib/active_support/testing/setup_and_teardown.rb +8 -11
  111. data/lib/active_support/time_with_zone.rb +6 -3
  112. data/lib/active_support/values/time_zone.rb +26 -8
  113. data/lib/active_support/version.rb +2 -2
  114. data/lib/active_support/whiny_nil.rb +1 -1
  115. data/lib/active_support/xml_mini/jdom.rb +1 -1
  116. data/lib/active_support/xml_mini/libxml.rb +1 -0
  117. data/lib/active_support/xml_mini/libxmlsax.rb +2 -1
  118. data/lib/active_support/xml_mini/nokogiri.rb +1 -0
  119. data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
  120. data/lib/active_support/xml_mini/rexml.rb +1 -0
  121. data/lib/active_support/xml_mini.rb +8 -3
  122. data/lib/active_support.rb +4 -2
  123. metadata +70 -32
  124. checksums.yaml +0 -7
  125. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  126. data/lib/active_support/core_ext/cgi.rb +0 -1
  127. data/lib/active_support/core_ext/object/returning.rb +0 -43
  128. data/lib/active_support/json/backends/jsongem.rb +0 -47
  129. data/lib/active_support/json/backends/okjson.rb +0 -644
  130. data/lib/active_support/json/backends/yajl.rb +0 -44
  131. data/lib/active_support/json/backends/yaml.rb +0 -19
  132. data/lib/active_support/testing/default.rb +0 -9
@@ -1,38 +1,83 @@
1
- begin
2
- require 'ruby-prof'
3
-
4
- require 'fileutils'
5
- require 'rails/version'
6
- require 'active_support/core_ext/class/delegating_attributes'
7
- require 'active_support/core_ext/string/inflections'
8
-
9
- module ActiveSupport
10
- module Testing
11
- module Performance
12
- DEFAULTS =
13
- if benchmark = ARGV.include?('--benchmark') # HAX for rake test
14
- { :benchmark => true,
15
- :runs => 4,
16
- :metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
17
- :output => 'tmp/performance' }
18
- else
19
- { :benchmark => false,
20
- :runs => 1,
21
- :min_percent => 0.01,
22
- :metrics => [:process_time, :memory, :objects],
23
- :formats => [:flat, :graph_html, :call_tree],
24
- :output => 'tmp/performance' }
25
- end.freeze
26
-
27
- def self.included(base)
28
- base.superclass_delegating_accessor :profile_options
29
- base.profile_options = DEFAULTS
1
+ require 'fileutils'
2
+ require 'rails/version'
3
+ require 'active_support/concern'
4
+ require 'active_support/core_ext/class/delegating_attributes'
5
+ require 'active_support/core_ext/string/inflections'
6
+ require 'action_view/helpers/number_helper'
7
+
8
+ module ActiveSupport
9
+ module Testing
10
+ module Performance
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ superclass_delegating_accessor :profile_options
15
+ self.profile_options = {}
16
+
17
+ if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
18
+ include ForMiniTest
19
+ else
20
+ include ForClassicTestUnit
21
+ end
22
+ end
23
+
24
+ # each implementation should define metrics and freeze the defaults
25
+ DEFAULTS =
26
+ if ARGV.include?('--benchmark') # HAX for rake test
27
+ { :runs => 4,
28
+ :output => 'tmp/performance',
29
+ :benchmark => true }
30
+ else
31
+ { :runs => 1,
32
+ :output => 'tmp/performance',
33
+ :benchmark => false }
34
+ end
35
+
36
+ def full_profile_options
37
+ DEFAULTS.merge(profile_options)
38
+ end
39
+
40
+ def full_test_name
41
+ "#{self.class.name}##{method_name}"
42
+ end
43
+
44
+ module ForMiniTest
45
+ def run(runner)
46
+ @runner = runner
47
+
48
+ run_warmup
49
+ if full_profile_options && metrics = full_profile_options[:metrics]
50
+ metrics.each do |metric_name|
51
+ if klass = Metrics[metric_name.to_sym]
52
+ run_profile(klass.new)
53
+ end
54
+ end
55
+ end
56
+
57
+ return
30
58
  end
31
59
 
32
- def full_test_name
33
- "#{self.class.name}##{method_name}"
60
+ def run_test(metric, mode)
61
+ result = '.'
62
+ begin
63
+ run_callbacks :setup
64
+ setup
65
+ metric.send(mode) { __send__ method_name }
66
+ rescue Exception => e
67
+ result = @runner.puke(self.class, method_name, e)
68
+ ensure
69
+ begin
70
+ teardown
71
+ run_callbacks :teardown, :enumerator => :reverse_each
72
+ rescue Exception => e
73
+ result = @runner.puke(self.class, method_name, e)
74
+ end
75
+ end
76
+ result
34
77
  end
78
+ end
35
79
 
80
+ module ForClassicTestUnit
36
81
  def run(result)
37
82
  return if method_name =~ /^default_test$/
38
83
 
@@ -40,11 +85,13 @@ begin
40
85
  @_result = result
41
86
 
42
87
  run_warmup
43
- if profile_options && metrics = profile_options[:metrics]
88
+ if full_profile_options && metrics = full_profile_options[:metrics]
44
89
  metrics.each do |metric_name|
45
90
  if klass = Metrics[metric_name.to_sym]
46
91
  run_profile(klass.new)
47
92
  result.add_run
93
+ else
94
+ puts '%20s: unsupported' % metric_name
48
95
  end
49
96
  end
50
97
  end
@@ -57,7 +104,7 @@ begin
57
104
  setup
58
105
  metric.send(mode) { __send__ @method_name }
59
106
  rescue ::Test::Unit::AssertionFailedError => e
60
- add_failure(e.message, e.backtrace)
107
+ add_failure(e.message, e.backtrace)
61
108
  rescue StandardError, ScriptError => e
62
109
  add_error(e)
63
110
  ensure
@@ -70,356 +117,201 @@ begin
70
117
  add_error(e)
71
118
  end
72
119
  end
120
+ end
73
121
 
74
- protected
75
- def run_warmup
76
- GC.start
122
+ protected
123
+ # overridden by each implementation
124
+ def run_gc; end
77
125
 
78
- time = Metrics::Time.new
79
- run_test(time, :benchmark)
80
- puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
126
+ def run_warmup
127
+ run_gc
81
128
 
82
- GC.start
83
- end
129
+ time = Metrics::Time.new
130
+ run_test(time, :benchmark)
131
+ puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
84
132
 
85
- def run_profile(metric)
86
- klass = profile_options[:benchmark] ? Benchmarker : Profiler
87
- performer = klass.new(self, metric)
133
+ run_gc
134
+ end
88
135
 
89
- performer.run
90
- puts performer.report
91
- performer.record
92
- end
136
+ def run_profile(metric)
137
+ klass = full_profile_options[:benchmark] ? Benchmarker : Profiler
138
+ performer = klass.new(self, metric)
93
139
 
94
- class Performer
95
- delegate :run_test, :profile_options, :full_test_name, :to => :@harness
140
+ performer.run
141
+ puts performer.report
142
+ performer.record
143
+ end
96
144
 
97
- def initialize(harness, metric)
98
- @harness, @metric = harness, metric
99
- end
145
+ class Performer
146
+ delegate :run_test, :full_profile_options, :full_test_name, :to => :@harness
147
+
148
+ def initialize(harness, metric)
149
+ @harness, @metric, @supported = harness, metric, false
150
+ end
100
151
 
101
- def report
102
- rate = @total / profile_options[:runs]
152
+ def report
153
+ if @supported
154
+ rate = @total / full_profile_options[:runs]
103
155
  '%20s: %s' % [@metric.name, @metric.format(rate)]
156
+ else
157
+ '%20s: unsupported' % @metric.name
104
158
  end
105
-
106
- protected
107
- def output_filename
108
- "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
109
- end
110
159
  end
111
160
 
112
- class Benchmarker < Performer
113
- def run
114
- profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
115
- @total = @metric.total
161
+ protected
162
+ def output_filename
163
+ "#{full_profile_options[:output]}/#{full_test_name}_#{@metric.name}"
116
164
  end
165
+ end
117
166
 
118
- def record
119
- avg = @metric.total / profile_options[:runs].to_i
120
- now = Time.now.utc.xmlschema
121
- with_output_file do |file|
122
- file.puts "#{avg},#{now},#{environment}"
123
- end
124
- end
167
+ # overridden by each implementation
168
+ class Profiler < Performer
169
+ def time_with_block
170
+ before = Time.now
171
+ yield
172
+ Time.now - before
173
+ end
125
174
 
126
- def environment
127
- unless defined? @env
128
- app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
175
+ def run; end
176
+ def record; end
177
+ end
129
178
 
130
- rails = Rails::VERSION::STRING
131
- if File.directory?('vendor/rails/.git')
132
- Dir.chdir('vendor/rails') do
133
- rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
134
- end
135
- end
179
+ class Benchmarker < Performer
180
+ def initialize(*args)
181
+ super
182
+ @supported = @metric.respond_to?('measure')
183
+ end
136
184
 
137
- ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
138
- ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
185
+ def run
186
+ return unless @supported
139
187
 
140
- @env = [app, rails, ruby, RUBY_PLATFORM] * ','
141
- end
188
+ full_profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
189
+ @total = @metric.total
190
+ end
142
191
 
143
- @env
192
+ def record
193
+ avg = @metric.total / full_profile_options[:runs].to_i
194
+ now = Time.now.utc.xmlschema
195
+ with_output_file do |file|
196
+ file.puts "#{avg},#{now},#{environment}"
144
197
  end
198
+ end
145
199
 
146
- protected
147
- HEADER = 'measurement,created_at,app,rails,ruby,platform'
148
-
149
- def with_output_file
150
- fname = output_filename
151
-
152
- if new = !File.exist?(fname)
153
- FileUtils.mkdir_p(File.dirname(fname))
154
- end
200
+ def environment
201
+ unless defined? @env
202
+ app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
155
203
 
156
- File.open(fname, 'ab') do |file|
157
- file.puts(HEADER) if new
158
- yield file
204
+ rails = Rails::VERSION::STRING
205
+ if File.directory?('vendor/rails/.git')
206
+ Dir.chdir('vendor/rails') do
207
+ rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
159
208
  end
160
209
  end
161
210
 
162
- def output_filename
163
- "#{super}.csv"
164
- end
165
- end
166
-
167
- class Profiler < Performer
168
- def initialize(*args)
169
- super
170
- @supported = @metric.measure_mode rescue false
171
- end
172
-
173
- def run
174
- return unless @supported
211
+ ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
212
+ ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
175
213
 
176
- RubyProf.measure_mode = @metric.measure_mode
177
- RubyProf.start
178
- RubyProf.pause
179
- profile_options[:runs].to_i.times { run_test(@metric, :profile) }
180
- @data = RubyProf.stop
181
- @total = @data.threads.values.sum(0) { |method_infos| method_infos.max.total_time }
214
+ @env = [app, rails, ruby, RUBY_PLATFORM] * ','
182
215
  end
183
216
 
184
- def report
185
- if @supported
186
- super
187
- else
188
- '%20s: unsupported' % @metric.name
189
- end
190
- end
217
+ @env
218
+ end
191
219
 
192
- def record
193
- return unless @supported
220
+ protected
221
+ HEADER = 'measurement,created_at,app,rails,ruby,platform'
194
222
 
195
- klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
223
+ def with_output_file
224
+ fname = output_filename
196
225
 
197
- klasses.each do |klass|
198
- fname = output_filename(klass)
226
+ if new = !File.exist?(fname)
199
227
  FileUtils.mkdir_p(File.dirname(fname))
200
- File.open(fname, 'wb') do |file|
201
- klass.new(@data).print(file, profile_options.slice(:min_percent))
202
- end
203
228
  end
204
- end
205
229
 
206
- protected
207
- def output_filename(printer_class)
208
- suffix =
209
- case printer_class.name.demodulize
210
- when 'FlatPrinter'; 'flat.txt'
211
- when 'FlatPrinterWithLineNumbers'; 'flat_line_numbers.txt'
212
- when 'GraphPrinter'; 'graph.txt'
213
- when 'GraphHtmlPrinter'; 'graph.html'
214
- when 'GraphYamlPrinter'; 'graph.yml'
215
- when 'CallTreePrinter'; 'tree.txt'
216
- when 'CallStackPrinter'; 'stack.html'
217
- when 'DotPrinter'; 'graph.dot'
218
- else printer_class.name.sub(/Printer$/, '').underscore
219
- end
220
-
221
- "#{super()}_#{suffix}"
230
+ File.open(fname, 'ab') do |file|
231
+ file.puts(HEADER) if new
232
+ yield file
222
233
  end
223
- end
224
-
225
- module Metrics
226
- def self.[](name)
227
- const_get(name.to_s.camelize)
228
- rescue NameError
229
- nil
230
234
  end
231
235
 
232
- class Base
233
- attr_reader :total
234
-
235
- def initialize
236
- @total = 0
237
- end
238
-
239
- def name
240
- @name ||= self.class.name.demodulize.underscore
241
- end
242
-
243
- def measure_mode
244
- self.class::Mode
245
- end
246
-
247
- def measure
248
- 0
249
- end
250
-
251
- def benchmark
252
- with_gc_stats do
253
- before = measure
254
- yield
255
- @total += (measure - before)
256
- end
257
- end
258
-
259
- def profile
260
- RubyProf.resume
261
- yield
262
- ensure
263
- RubyProf.pause
264
- end
265
-
266
- protected
267
- # Ruby 1.9 with GC::Profiler
268
- if defined?(GC::Profiler)
269
- def with_gc_stats
270
- GC::Profiler.enable
271
- GC.start
272
- yield
273
- ensure
274
- GC::Profiler.disable
275
- end
276
-
277
- # Ruby 1.8 + ruby-prof wrapper (enable/disable stats for Benchmarker)
278
- elsif GC.respond_to?(:enable_stats)
279
- def with_gc_stats
280
- GC.enable_stats
281
- yield
282
- ensure
283
- GC.disable_stats
284
- end
285
-
286
- else
287
- def with_gc_stats
288
- yield
289
- end
290
- end
236
+ def output_filename
237
+ "#{super}.csv"
291
238
  end
239
+ end
292
240
 
293
- class Time < Base
294
- def measure
295
- ::Time.now.to_f
296
- end
241
+ module Metrics
242
+ def self.[](name)
243
+ const_get(name.to_s.camelize)
244
+ rescue NameError
245
+ nil
246
+ end
297
247
 
298
- def format(measurement)
299
- if measurement < 1
300
- '%d ms' % (measurement * 1000)
301
- else
302
- '%.2f sec' % measurement
303
- end
304
- end
305
- end
248
+ class Base
249
+ include ActionView::Helpers::NumberHelper
306
250
 
307
- class ProcessTime < Time
308
- Mode = RubyProf::PROCESS_TIME
251
+ attr_reader :total
309
252
 
310
- def measure
311
- RubyProf.measure_process_time
312
- end
253
+ def initialize
254
+ @total = 0
313
255
  end
314
256
 
315
- class WallTime < Time
316
- Mode = RubyProf::WALL_TIME
317
-
318
- def measure
319
- RubyProf.measure_wall_time
320
- end
257
+ def name
258
+ @name ||= self.class.name.demodulize.underscore
321
259
  end
322
260
 
323
- class CpuTime < Time
324
- Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
325
-
326
- def initialize(*args)
327
- # FIXME: yeah my CPU is 2.33 GHz
328
- RubyProf.cpu_frequency = 2.33e9 unless RubyProf.cpu_frequency > 0
329
- super
330
- end
331
-
332
- def measure
333
- RubyProf.measure_cpu_time
261
+ def benchmark
262
+ with_gc_stats do
263
+ before = measure
264
+ yield
265
+ @total += (measure - before)
334
266
  end
335
267
  end
336
268
 
337
- class Memory < Base
338
- Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
269
+ # overridden by each implementation
270
+ def profile; end
339
271
 
340
- # Ruby 1.9 + GCdata patch
341
- if GC.respond_to?(:malloc_allocated_size)
342
- def measure
343
- GC.malloc_allocated_size / 1024.0
344
- end
345
-
346
- # Ruby 1.8 + ruby-prof wrapper
347
- elsif RubyProf.respond_to?(:measure_memory)
348
- def measure
349
- RubyProf.measure_memory / 1024.0
350
- end
351
- end
272
+ protected
273
+ # overridden by each implementation
274
+ def with_gc_stats; end
275
+ end
352
276
 
353
- def format(measurement)
354
- '%.2f KB' % measurement
355
- end
277
+ class Time < Base
278
+ def measure
279
+ ::Time.now.to_f
356
280
  end
357
281
 
358
- class Objects < Base
359
- Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
360
-
361
- # Ruby 1.9 + GCdata patch
362
- if GC.respond_to?(:malloc_allocations)
363
- def measure
364
- GC.malloc_allocations
365
- end
366
-
367
- # Ruby 1.8 + ruby-prof wrapper
368
- elsif RubyProf.respond_to?(:measure_allocations)
369
- def measure
370
- RubyProf.measure_allocations
371
- end
372
- end
373
-
374
- def format(measurement)
375
- measurement.to_i.to_s
282
+ def format(measurement)
283
+ if measurement < 1
284
+ '%d ms' % (measurement * 1000)
285
+ else
286
+ '%.2f sec' % measurement
376
287
  end
377
288
  end
289
+ end
378
290
 
379
- class GcRuns < Base
380
- Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
381
-
382
- # Ruby 1.9
383
- if GC.respond_to?(:count)
384
- def measure
385
- GC.count
386
- end
387
-
388
- # Ruby 1.8 + ruby-prof wrapper
389
- elsif RubyProf.respond_to?(:measure_gc_runs)
390
- def measure
391
- RubyProf.measure_gc_runs
392
- end
393
- end
394
-
395
- def format(measurement)
396
- measurement.to_i.to_s
397
- end
291
+ class Amount < Base
292
+ def format(measurement)
293
+ number_with_delimiter(measurement.floor)
398
294
  end
295
+ end
399
296
 
400
- class GcTime < Base
401
- Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
402
-
403
- # Ruby 1.9 with GC::Profiler
404
- if defined?(GC::Profiler) && GC::Profiler.respond_to?(:total_time)
405
- def measure
406
- GC::Profiler.total_time
407
- end
408
-
409
- # Ruby 1.8 + ruby-prof wrapper
410
- elsif RubyProf.respond_to?(:measure_gc_time)
411
- def measure
412
- RubyProf.measure_gc_time / 1000
413
- end
414
- end
415
-
416
- def format(measurement)
417
- '%.2f ms' % measurement
418
- end
297
+ class DigitalInformationUnit < Base
298
+ def format(measurement)
299
+ number_to_human_size(measurement, :precision => 2)
419
300
  end
420
301
  end
302
+
303
+ # each implementation provides its own metrics like ProcessTime, Memory or GcRuns
421
304
  end
422
305
  end
423
306
  end
424
- rescue LoadError
307
+ end
308
+
309
+ RUBY_ENGINE = 'ruby' unless defined?(RUBY_ENGINE) # mri 1.8
310
+ case RUBY_ENGINE
311
+ when 'ruby' then require 'active_support/testing/performance/ruby'
312
+ when 'rbx' then require 'active_support/testing/performance/rubinius'
313
+ when 'jruby' then require 'active_support/testing/performance/jruby'
314
+ else
315
+ $stderr.puts 'Your ruby interpreter is not supported for benchmarking.'
316
+ exit
425
317
  end