File: benchmark

package info (click to toggle)
ruby-benchmark-suite 1.0.0%2Bgit.20130122.5bded6-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 152 kB
  • sloc: ruby: 290; makefile: 12
file content (179 lines) | stat: -rwxr-xr-x 3,575 bytes parent folder | download | duplicates (2)
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