bench/runner.rb in sanford-0.1.0 vs bench/runner.rb in sanford-0.2.0

- old
+ new

@@ -41,23 +41,37 @@ output('.', false) if ((index - 1) % 100 == 0) && !show_result end output("\n", false) total_time = benchmarks.inject(0){|s, n| s + n } + average = total_time / benchmarks.size data = { :number_of_requests => times, :total_time_taken => self.round_and_display(total_time), - :average_time_taken => self.round_and_display(total_time / benchmarks.size), + :average_time_taken => self.round_and_display(average), :min_time_taken => self.round_and_display(benchmarks.min), :max_time_taken => self.round_and_display(benchmarks.max) } size = data.values.map(&:size).max output "Total Time: #{data[:total_time_taken].rjust(size)}ms" output "Average Time: #{data[:average_time_taken].rjust(size)}ms" output "Min Time: #{data[:min_time_taken].rjust(size)}ms" output "Max Time: #{data[:max_time_taken].rjust(size)}ms" + output "\n" + + distribution = Distribution.new(benchmarks) + + output "Distribution (number of requests):" + distribution.each do |grouping| + output " #{grouping.time}ms: #{grouping.number_of_requests}" + grouping.precise_groupings.each do |precise_grouping| + output " #{precise_grouping.time}ms: #{precise_grouping.number_of_requests}" + end + end + + output "\n" end protected def hit_service(version, name, params, show_result) @@ -93,9 +107,116 @@ end def display_time(time) integer, fractional = time.to_s.split('.') [ integer, fractional.ljust(4, '0') ].join('.') + end + + class Distribution + + def initialize(benchmarks) + hash = benchmarks.inject({}) do |hash, benchmark| + index = Index.new(benchmark).number + hash[index] ||= Grouping.new(index) + hash[index].add(benchmark) + hash + end + @groupings = hash.values.sort + end + + def each(&block) + @groupings.each(&block) + end + + class BaseGrouping + + def self.max_time(time = nil) + size = time.to_s.size + @max_time = size if size > @max_time.to_i + @max_time + end + + def self.max_number(number = nil) + size = number.to_s.size + @max_size = size if size > @max_size.to_i + @max_size + end + + attr_reader :name + + def initialize(index) + @name = index.to_s + @set = [] + self.class.max_time(index.to_s.size) + end + + def add(benchmark) + result = @set.push(benchmark) + self.class.max_number(@set.size.to_s.size) + result + end + + def time + @name.rjust(self.class.max_time) + end + + def number_of_requests + @set.size.to_s.rjust(self.class.max_number) + end + + def <=>(other) + self.name.to_f <=> other.name.to_f + end + + end + + class Grouping < BaseGrouping + + def initialize(index) + super + @precise_groupings = {} + end + + def add(benchmark) + add_precise_grouping(benchmark) if self.collect_precise? + super(benchmark) + end + + def collect_precise? + @name.to_i <= 1 + end + + def precise_groupings + @precise_groupings.values.sort + end + + protected + + def add_precise_grouping(benchmark) + index = PreciseIndex.new(benchmark).number + @precise_groupings[index] ||= BaseGrouping.new(index) + @precise_groupings[index].add(benchmark) + end + + end + + class Index < Struct.new(:number) + + def initialize(benchmark) + super benchmark.to_i + end + end + + class PreciseIndex < Struct.new(:number) + + MODIFIER = 10.to_f + + def initialize(benchmark) + super((benchmark * MODIFIER).to_i / MODIFIER) + end + + end + end end end