lib/benchmark_driver/repeater.rb in benchmark_driver-0.15.6 vs lib/benchmark_driver/repeater.rb in benchmark_driver-0.15.7
- old
+ new
@@ -1,11 +1,11 @@
require 'benchmark_driver/struct'
module BenchmarkDriver
# Repeat calling block and return desired result: "best", "worst" or "average".
module Repeater
- VALID_TYPES = %w[best worst average]
+ VALID_TYPES = %w[best worst average median]
RepeatResult = ::BenchmarkDriver::Struct.new(
:value, # the value desired by --repeat-result
:all_values, # all benchmark results. Used by --output=all.
)
@@ -25,10 +25,12 @@
best_result(values, larger_better)
when 'worst'
best_result(values, !larger_better)
when 'average'
average_result(values, rest_on_average)
+ when 'median'
+ median_result(values, rest_on_average)
else
raise "unexpected repeat_result #{config.repeat_result.inspect}"
end
RepeatResult.new(value: desired_value, all_values: extract_values(values))
end
@@ -54,9 +56,42 @@
values.first.size.times.map do |index|
values.map { |v| v[index] }.inject(&:+) / values.first.size.to_f
end
else
raise "unexpected rest_on_average #{rest_on_average.inspect}"
+ end
+ end
+
+ def median_result_i(a)
+ b = a.dup
+ b.sort!
+ x = y = nil
+ until b.empty? do
+ x = b.pop
+ y = b.shift
+ end
+ x || y
+ end
+
+ def median_result(values, rest_on_average)
+ case values.first
+ when Numeric then
+ median_result values
+ when Array then
+ case rest_on_average
+ when :first
+ rest = values.first[1..-1]
+ median = median_result_i(values.map(&:first))
+ [median, *rest]
+ when :average
+ values.first.size.times.map do |i|
+ median_result_i(values.map {|j| j[i] })
+ end
+ else
+ raise "unexpected rest_on_average #{rest_on_average.inspect}"
+ end
+ else
+ raise "unexpected values #{values.class}"
end
end
def extract_values(values)
values.map do |value|