Class: Benchmark::IPS::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/benchmark/ips/job.rb

Defined Under Namespace

Classes: Entry

Constant Summary collapse

MICROSECONDS_PER_100MS =
100_000
MICROSECONDS_PER_SECOND =
1_000_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Job

Returns a new instance of Job.



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/benchmark/ips/job.rb', line 86

def initialize opts={}
  @suite = opts[:suite] || nil
  @quiet = opts[:quiet] || false
  @list = []
  @compare = false

  @timing = {}
  @full_report = Report.new

  # defaults
  @warmup = 2
  @time = 5
end

Instance Attribute Details

#compareObject (readonly)

Boolean determining whether to run comparison utility



78
79
80
# File 'lib/benchmark/ips/job.rb', line 78

def compare
  @compare
end

#full_reportObject (readonly)

Report object containing information about the run



81
82
83
# File 'lib/benchmark/ips/job.rb', line 81

def full_report
  @full_report
end

#listObject (readonly)

An array of 2-element arrays, consisting of label and block pairs.



75
76
77
# File 'lib/benchmark/ips/job.rb', line 75

def list
  @list
end

#timeObject

Returns the value of attribute time.



83
84
85
# File 'lib/benchmark/ips/job.rb', line 83

def time
  @time
end

#timingObject (readonly)

Returns the value of attribute timing.



84
85
86
# File 'lib/benchmark/ips/job.rb', line 84

def timing
  @timing
end

#warmupObject

Returns the value of attribute warmup.



83
84
85
# File 'lib/benchmark/ips/job.rb', line 83

def warmup
  @warmup
end

Instance Method Details

#compare!Object



109
110
111
# File 'lib/benchmark/ips/job.rb', line 109

def compare!
  @compare = true
end

#compare?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/benchmark/ips/job.rb', line 105

def compare?
  @compare
end

#config(opts) ⇒ Object



100
101
102
103
# File 'lib/benchmark/ips/job.rb', line 100

def config opts
  @warmup = opts[:warmup] if opts[:warmup]
  @time = opts[:time] if opts[:time]
end

#create_report(item, measured_us, iter, avg_ips, sd_ips, cycles) ⇒ Object



237
238
239
# File 'lib/benchmark/ips/job.rb', line 237

def create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)
  @full_report.add_entry item.label, measured_us, iter, avg_ips, sd_ips, cycles
end

#cycles_per_100ms(time_msec, iters) ⇒ Object

calculate the cycles needed to run for approx 100ms given the number of iterations to run the given time



131
132
133
134
135
# File 'lib/benchmark/ips/job.rb', line 131

def cycles_per_100ms time_msec, iters
  cycles = ((MICROSECONDS_PER_100MS / time_msec) * iters).to_i
  cycles = 1 if cycles <= 0
  cycles
end

#item(label = "", str = nil, &blk) ⇒ Object Also known as: report

Registers the given label and block pair in the job list.

Raises:

  • (ArgumentError)


116
117
118
119
120
121
122
123
124
125
126
# File 'lib/benchmark/ips/job.rb', line 116

def item(label="", str=nil, &blk) # :yield:
  if blk and str
    raise ArgumentError, "specify a block and a str, but not both"
  end

  action = str || blk
  raise ArgumentError, "no block or string" unless action

  @list.push Entry.new(label, action)
  self
end

#iterations_per_sec(cycles, time_us) ⇒ Object

calculate the interations per second given the number of cycles run and the time in microseconds that elapsed



145
146
147
# File 'lib/benchmark/ips/job.rb', line 145

def iterations_per_sec cycles, time_us
  MICROSECONDS_PER_SECOND * (cycles.to_f / time_us.to_f)
end

#runObject



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/benchmark/ips/job.rb', line 181

def run
  @list.each do |item|
    @suite.running item.label, @time if @suite

    unless @quiet
      $stdout.print item.label_rjust
    end

    Timing.clean_env

    iter = 0

    target = Time.now + @time

    measurements_us = []

    # running this number of cycles should take around 100ms
    cycles = @timing[item]

    while Time.now < target
      before = Time.now
      item.call_times cycles
      after = Time.now

      # If for some reason the timing said this took no time (O_o)
      # then ignore the iteration entirely and start another.
      #
      iter_us = time_us before, after
      next if iter_us <= 0.0

      iter += cycles

      measurements_us << iter_us
    end

    measured_us = measurements_us.inject(0) { |a,i| a + i }

    all_ips = measurements_us.map { |time_us|
      iterations_per_sec cycles, time_us
    }

    avg_ips = Timing.mean(all_ips)
    sd_ips =  Timing.stddev(all_ips).round

    rep = create_report(item, measured_us, iter, avg_ips, sd_ips, cycles)

    $stdout.puts " #{rep.body}" unless @quiet

    @suite.add_report rep, caller(1).first if @suite
  end
end

#run_comparisonObject



233
234
235
# File 'lib/benchmark/ips/job.rb', line 233

def run_comparison
  @full_report.run_comparison
end

#run_warmupObject



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
# File 'lib/benchmark/ips/job.rb', line 149

def run_warmup
  @list.each do |item|
    @suite.warming item.label, @warmup if @suite

    unless @quiet
      $stdout.printf item.label_rjust
    end

    Timing.clean_env

    before = Time.now
    target = Time.now + @warmup

    warmup_iter = 0

    while Time.now < target
      item.call_times(1)
      warmup_iter += 1
    end

    after = Time.now

    warmup_time_us = time_us before, after

    @timing[item] = cycles_per_100ms warmup_time_us, warmup_iter

    $stdout.printf "%10d i/100ms\n", @timing[item] unless @quiet

    @suite.warmup_stats warmup_time_us, @timing[item] if @suite
  end
end

#time_us(before, after) ⇒ Object

calculate the difference in microseconds between before and after



139
140
141
# File 'lib/benchmark/ips/job.rb', line 139

def time_us before, after
  (after.to_f - before.to_f) * MICROSECONDS_PER_SECOND
end