class DiffBench::Runner
Constants
- COLORS
Public Class Methods
color(text, color_string)
click to toggle source
# File lib/diffbench.rb, line 136 def self.color(text, color_string) code = COLORS[color_string] self.color_enabled? ? "\e[#{code}m#{text}\e[0m" : text end
color_enabled?()
click to toggle source
# File lib/diffbench.rb, line 141 def self.color_enabled? true end
new(*args)
click to toggle source
# File lib/diffbench.rb, line 14 def initialize(*args) parser = OptionParser.new do |opts| opts.banner = <<-DOC Usage: diffbench [options] file When working tree is dirty default is run benchmark againts dirty tree and clean tree. When working tree is clean default is run benchmark against current head and previous commit. DOC opts.on("-r", '--revision [REVISIONS]', 'Specify revisions to run benchmark (comma separated). Example: master,f9a845,v3.1.4') do |value| if tree_dirty? raise Error, "Working tree is dirty." end @revisions = value.split(",") end opts.on("-b", '--before [COMMAND]', 'Specify command to run before each benchmark run. e.g. bundle install') do |value| @before_command = value end opts.on_tail('-h', '--help', 'Show this help') do output opts exit end end parser.parse!(args) @file = args.first or raise Error, 'File not specified' end
Public Instance Methods
improvement_percentage(before_patch, after_patch)
click to toggle source
# File lib/diffbench.rb, line 132 def improvement_percentage(before_patch, after_patch) (((before_patch.real - after_patch.real).to_f / before_patch.real) * 100).round end
output_improvement(before, after)
click to toggle source
# File lib/diffbench.rb, line 126 def output_improvement(before, after) improvement = improvement_percentage(before, after) color_string = result_color(improvement) output self.class.color("Improvement: #{improvement}%", color_string).strip end
print_results(results)
click to toggle source
# File lib/diffbench.rb, line 68 def print_results(results) output "" #TODO set caption the right way caption = "Before patch: ".gsub(/./, " ") + Benchmark::Tms::CAPTION output caption tests = results.values.first.keys tests.each do |test| output(("-" * (caption.size - test.size)) + test) results.each do |revision, benchmark| output "#{revision}: #{benchmark[test].format}" end if results.size == 2 output_improvement(*results.values.map {|b| b[test]}) end output "" end end
run()
click to toggle source
# File lib/diffbench.rb, line 42 def run if @revisions run_revisions else run_current_head end end
run_current_head()
click to toggle source
# File lib/diffbench.rb, line 86 def run_current_head output "Running benchmark with current working tree" first_run = run_file if tree_dirty? output "Stashing changes" git_run "stash" output "Running benchmark with clean working tree" begin second_run = run_file ensure output "Applying stashed changes back" git_run "stash pop" end elsif branch = current_head output "Checkout HEAD^" git_run "checkout 'HEAD^'" output "Running benchmark with HEAD^" begin second_run = run_file ensure output "Checkout to previous HEAD again" git_run "checkout #{branch}" end else raise Error, "No current branch." end output "" caption = "Before patch: ".gsub(/./, " ") + Benchmark::Tms::CAPTION output caption first_run.keys.each do |test| output(("-" * (caption.size - test.size)) + test) before_patch = second_run[test] after_patch = first_run[test] output "After patch: #{after_patch.format}" output "Before patch: #{before_patch.format}" output_improvement(before_patch, after_patch) output "" end end
run_revisions()
click to toggle source
# File lib/diffbench.rb, line 50 def run_revisions branch = current_head results = begin @revisions.inject({}) do |result, revision| output "Checkout to #{revision}" output "Run benchmark with #{revision}" git_run("checkout '#{revision}'") result[revision] = run_file result end ensure output "Checkout to #{branch}" git_run("checkout '#{branch}'") end print_results(results) end
Protected Instance Methods
current_head()
click to toggle source
# File lib/diffbench.rb, line 155 def current_head branch = git.current_branch.to_s return branch if !(branch == "(no branch)") branch = git_run("symbolic-ref HEAD").gsub(/^refs\/head\//, "") return branch unless branch.empty? rescue Git::GitExecuteError branch = git_run("rev-parse HEAD")[0..7] return branch end
discover_git_dir()
click to toggle source
# File lib/diffbench.rb, line 195 def discover_git_dir tokens = ENV['PWD'].split("/") while tokens.any? path = tokens.join("/") if File.exists?(path + "/.git") return path end tokens.pop end raise Error, "Git working dir not found" end
git()
click to toggle source
# File lib/diffbench.rb, line 191 def git @git ||= Git.open(discover_git_dir) end
git_run(command)
click to toggle source
# File lib/diffbench.rb, line 187 def git_run(command) git.lib.send(:command, command) end
output(string)
click to toggle source
# File lib/diffbench.rb, line 212 def output(string) puts string end
result_color(improvement)
click to toggle source
# File lib/diffbench.rb, line 147 def result_color(improvement) if (-5..5).include?(improvement) :yellow else improvement > 0 ? :green : :red end end
run_file()
click to toggle source
# File lib/diffbench.rb, line 165 def run_file output `#{@before_command}` if @before_command output = `ruby -I#{File.dirname(__FILE__)} #{@file}` output.split("\n").select! do |line| if line.start_with?("diffbench:") true else output line end end if $?.to_i > 0 raise Error, "Error exit code: #{$?.to_i}" end begin result = Encoder.decode(output) raise Error, "Can not parse result of ruby script: \n #{output}" unless result.is_a?(Hash) result rescue Psych::SyntaxError raise Error, "Can not run ruby script: \n#{output}" end end
tree_dirty?()
click to toggle source
# File lib/diffbench.rb, line 207 def tree_dirty? status = git.status status.deleted.any? || status.changed.any? end