Skip to content

Instantly share code, notes, and snippets.

@chrisseaton
Created October 4, 2015 13:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisseaton/1c4cb91f3c95ddcf2d1e to your computer and use it in GitHub Desktop.
Save chrisseaton/1c4cb91f3c95ddcf2d1e to your computer and use it in GitHub Desktop.
# This file modifies benchmark-ips to better accommodate the optimisation
# characteristics of sophisticated implementations of Ruby that have a very
# large difference between cold and warmed up performance, and that apply
# optimisations such as value profiling or other speculation on runtime values.
# Recommended to be used with a large (60s) warmup and (30s) measure time. This
# has been modified to be the default. Note that on top of that, it now runs
# warmup five times, so generating the report will be a lot slower than
# before.
# Code is modified from benchmark-ips
# Copyright (c) 2015 Evan Phoenix
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the 'Software'), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
module Benchmark
module IPS
class Job
def run_warmup
@list.each do |item|
@suite.warming item.label, @warmup if @suite
unless @quiet
$stdout.print item.label_rjust
end
Timing.clean_env
# Modification - run with different iteration parameters to defeat
# value profiling and other speculation on runtime values.
item.call_times 1
item.call_times 2
item.call_times 3
# Modification - actual time to warm up - not measured
target = Time.now + @warmup
while Time.now < target
item.call_times 1
end
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
# Modification - warm up again with this new iteration value that we
# haven't run before.
cycles = @timing[item]
target = Time.now + @warmup
while Time.now < target
item.call_times cycles
end
# Modification repeat the scaling again
before = Time.now
target = Time.now + @warmup
warmup_iter = 0
while Time.now < target
item.call_times cycles
warmup_iter += cycles
end
after = Time.now
warmup_time_us = time_us before, after
@timing[item] = cycles_per_100ms warmup_time_us, warmup_iter
case Benchmark::IPS.options[:format]
when :human
$stdout.printf "%s i/100ms\n", Helpers.scale(@timing[item]) unless @quiet
else
$stdout.printf "%10d i/100ms\n", @timing[item] unless @quiet
end
@suite.warmup_stats warmup_time_us, @timing[item] if @suite
# Modification - warm up again with this new iteration value that we
# haven't run before.
cycles = @timing[item]
target = Time.now + @warmup
while Time.now < target
item.call_times cycles
end
end
end
alias_method :old_initialize, :initialize
def initialize opts={}
old_initialize opts
@warmup = 60
@time = 30
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment