diff options
Diffstat (limited to 'dragon/benchmark.rb')
| -rw-r--r-- | dragon/benchmark.rb | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/dragon/benchmark.rb b/dragon/benchmark.rb new file mode 100644 index 0000000..38ea991 --- /dev/null +++ b/dragon/benchmark.rb @@ -0,0 +1,111 @@ +# coding: utf-8 +# Copyright 2019 DragonRuby LLC +# MIT License +# benchmark.rb has been released under MIT (*only this file*). + +module GTK + class Runtime + module Benchmark + def benchmark_single iterations, name, proc + log <<-S +** Invoking :#{name}... +S + idx = 0 + r = nil + time_start = Time.now + while idx < iterations + r = proc.call + idx += 1 + end + result = (Time.now - time_start).round 3 + + { name: name, + time: result, + time_ms: (result * 1000).to_i } + end + + def benchmark opts = {} + iterations = opts.iterations + + log <<-S +* BENCHMARK: Started +** Caller: #{(caller || []).first} +** Iterations: #{iterations} +S + procs = opts.find_all { |k, v| v.respond_to? :call } + + times = procs.map do |(name, proc)| + benchmark_single iterations, name, proc + end.sort_by { |r| r.time } + + first_place = times.first + second_place = times.second || first_place + + times = times.map do |candidate| + average_time = first_place.time + .add(candidate.time) + .abs + .fdiv(2) + + difference_percentage = 0 + if average_time == 0 + difference_percentage = 0 + else + difference_percentage = first_place.time + .subtract(candidate.time) + .abs + .fdiv(average_time) + .imult(100) + end + + difference_time = ((first_place.time - candidate.time) * 1000).round + candidate.merge(difference_percentage: difference_percentage, + difference_time: difference_time) + end + + too_small_to_measure = false + if (first_place.time + second_place.time) == 0 + too_small_to_measure = true + difference_percentage = 0 + log <<-S +* BENCHMARK: Average time for experiments were too small. Increase the number of iterations. +S + else + difference_percentage = (((first_place.time - second_place.time).abs.fdiv((first_place.time + second_place.time).abs.fdiv(2))) * 100).round + end + + difference_time = first_place.time.-(second_place.time).*(1000).abs.round + + r = { + iterations: iterations, + first_place: first_place, + second_place: second_place, + difference_time: difference_time, + difference_percentage: difference_percentage, + times: times, + too_small_to_measure: too_small_to_measure + } + + log_message = [] + only_one_result = first_place.name == second_place.name + + if only_one_result + log <<-S +* BENCHMARK: #{r.first_place.name} completed in #{r.first_place.time_ms}ms." +S + else + log <<-S +* BENCHMARK: #{r.message} +** Fastest: #{r.first_place.name.inspect} +** Second: #{r.second_place.name.inspect} +** Margin: #{r.difference_percentage}% (#{r.difference_time.abs}ms) #{r.first_place.time_ms}ms vs #{r.second_place.time_ms}ms. +** Times: +#{r.times.map { |t| "*** #{t.name}: #{t.time_ms}ms (#{t.difference_percentage}% #{t.difference_time.abs}ms)." }.join("\n")} +S + end + + r + end + end + end +end |
