1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
#!/usr/bin/env ruby
require 'optparse'
require 'tempfile'
#lib_path = File.expand_path("../../lib", __FILE__)
# Debian lib path
lib_path = "/usr/lib/ruby/vendor_ruby"
$:.unshift lib_path
require 'benchmark/suite'
require 'benchmark/ips'
targets = []
extra = []
at_end = false
save = false
compare_targets = []
opt = OptionParser.new do |o|
o.on("-t", "--target TARGET", String,
"Use TARGET to compare against: r:ruby|r19:ruby19|x:rbx|j:jruby") do |t|
case t
when 'r', 'ruby'
targets << 'ruby'
when 'r19', 'ruby19'
targets << 'ruby19'
when 'x', 'rbx', 'rubinius'
targets << 'rbx'
when 'j', 'jruby'
targets << 'jruby'
else
# + disambiguates execution vs using a file
if t[0,1] == "+"
targets << t[1..-1]
elsif File.exists?(t)
begin
data = Marshal.load(File.read(t))
compare_targets << [t, data]
rescue TypeError
targets << t
end
else
targets << t
end
end
end
o.on("-p", "--profile", "Profile code while benchmarking (rbx only)") do
extra << "-Xprofile"
end
o.on("-e", "--end", "Report all stats after all suitse have run") do
at_end = true
end
o.on("-T OPTION", String, "Add more arguments to each target") do |t|
extra << t
end
o.on("-s", "--save PATH", String, "Save the results to a file") do |t|
save = t
end
end
opt.parse!
if targets.empty?
targets << "ruby"
end
if save and targets.size > 1
STDOUT.puts "Save mode only available with one target."
exit 1
end
opts = []
if at_end
opts << "--quiet"
end
results = targets.map do |t|
tf = Tempfile.new "benchmark"
tf.close
STDOUT.puts "=== #{t} ===" unless at_end
args = extra + ["-I#{lib_path}", "#{lib_path}/benchmark/suite-run.rb"]
args += opts
args << tf.path
args += ARGV
cmd, *rest = t.split(/\s+/)
args.unshift *rest
system cmd, *args
if $?.exitstatus != 0
puts "Error executing: #{cmd}"
nil
else
tf.open
[t, Marshal.load(tf.read)]
end
end
results.compact!
if save
name, data = results.last
File.open save, "w" do |f|
f << Marshal.dump(data)
end
STDOUT.puts "[Saved results to '#{save}']"
end
if at_end
results.each do |name, suite|
STDOUT.puts "=== #{name} ==="
suite.display
end
end
results += compare_targets
if results.size > 1
compared = Hash.new { |h,k| h[k] = [] }
results.each do |target, suite|
suite.reports.each do |name, reports|
reports.each do |rep|
compared["#{name}:#{rep.label}"] << [target, rep]
end
end
end
STDOUT.puts
compared.each do |name, reports|
if reports.size > 1
STDOUT.puts "Comparing #{name}:"
iter = false
sorted = reports.sort do |a,b|
if a[1].respond_to? :ips
iter = true
b[1].ips <=> a[1].ips
else
a[1].runtime <=> b[1].runtime
end
end
best_name, best_report = sorted.shift
if iter
STDOUT.printf "%20s: %10d i/s\n", best_name, best_report.ips
else
STDOUT.puts "#{best_name.rjust(20)}: #{best_report.runtime}s"
end
sorted.each do |entry|
name, report = entry
if iter
x = (best_report.ips.to_f / report.ips.to_f)
STDOUT.printf "%20s: %10d i/s - %.2fx slower\n", name, report.ips, x
else
x = "%.2f" % (report.ips.to_f / best_report.ips.to_f)
STDOUT.puts "#{name.rjust(20)}: #{report.runtime}s - #{x}x slower"
end
end
end
end
end
|