benchmark-interface 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.travis.yml +39 -0
- data/Gemfile +2 -0
- data/LICENCE +7 -0
- data/README.md +237 -0
- data/benchmark-interface.gemspec +20 -0
- data/bin/benchmark +15 -0
- data/examples/bench9000.rb +23 -0
- data/examples/bench9000micro.rb +31 -0
- data/examples/benchmark.rb +40 -0
- data/examples/bips.rb +34 -0
- data/examples/clamp.rb +17 -0
- data/examples/interface.rb +13 -0
- data/examples/long.rb +9 -0
- data/examples/mri.rb +15 -0
- data/examples/perfer.rb +25 -0
- data/examples/rbench.rb +46 -0
- data/examples/readme.rb +12 -0
- data/examples/script.rb +14 -0
- data/lib/benchmark-interface.rb +40 -0
- data/lib/benchmark-interface/backends/bench9000.rb +87 -0
- data/lib/benchmark-interface/backends/benchmark.rb +68 -0
- data/lib/benchmark-interface/backends/bips.rb +49 -0
- data/lib/benchmark-interface/backends/simple.rb +38 -0
- data/lib/benchmark-interface/benchmark-set.rb +85 -0
- data/lib/benchmark-interface/benchmark.rb +72 -0
- data/lib/benchmark-interface/frontends/bench9000.rb +21 -0
- data/lib/benchmark-interface/frontends/bench9000micro.rb +19 -0
- data/lib/benchmark-interface/frontends/benchmark.rb +50 -0
- data/lib/benchmark-interface/frontends/bips.rb +40 -0
- data/lib/benchmark-interface/frontends/mri.rb +84 -0
- data/lib/benchmark-interface/frontends/perfer.rb +27 -0
- data/lib/benchmark-interface/frontends/rbench.rb +64 -0
- data/lib/benchmark-interface/require.rb +38 -0
- data/lib/benchmark-interface/run.rb +111 -0
- data/lib/benchmark-interface/version.rb +13 -0
- data/tests/expected/bench9000-bips.txt +8 -0
- data/tests/expected/bench9000-bm.txt +2 -0
- data/tests/expected/bench9000-bmbm.txt +2 -0
- data/tests/expected/bench9000-simple.txt +2 -0
- data/tests/expected/bench9000micro-bips.txt +8 -0
- data/tests/expected/bench9000micro-bm.txt +2 -0
- data/tests/expected/bench9000micro-bmbm.txt +2 -0
- data/tests/expected/bench9000micro-simple.txt +2 -0
- data/tests/expected/benchmark-bips.txt +72 -0
- data/tests/expected/benchmark-bm.txt +12 -0
- data/tests/expected/benchmark-bmbm.txt +12 -0
- data/tests/expected/benchmark-simple.txt +22 -0
- data/tests/expected/bips-bips.txt +2 -0
- data/tests/expected/bips-bm.txt +7 -0
- data/tests/expected/bips-bmbm.txt +7 -0
- data/tests/expected/bips-simple.txt +11 -0
- data/tests/expected/interface-bips.txt +24 -0
- data/tests/expected/interface-bm.txt +4 -0
- data/tests/expected/interface-bmbm.txt +4 -0
- data/tests/expected/interface-simple.txt +6 -0
- data/tests/expected/long-bips.txt +9 -0
- data/tests/expected/long-bm.txt +2 -0
- data/tests/expected/long-bmbm.txt +2 -0
- data/tests/expected/long-simple.txt +2 -0
- data/tests/expected/mri-bips.txt +9 -0
- data/tests/expected/mri-bm.txt +2 -0
- data/tests/expected/mri-bmbm.txt +2 -0
- data/tests/expected/mri-simple.txt +2 -0
- data/tests/expected/perfer-bips.txt +20 -0
- data/tests/expected/perfer-bm.txt +4 -0
- data/tests/expected/perfer-bmbm.txt +4 -0
- data/tests/expected/perfer-simple.txt +5 -0
- data/tests/expected/rbench-bips.txt +42 -0
- data/tests/expected/rbench-bm.txt +7 -0
- data/tests/expected/rbench-bmbm.txt +7 -0
- data/tests/expected/rbench-simple.txt +12 -0
- data/tests/expected/readme-bips.txt +18 -0
- data/tests/expected/readme-bm.txt +3 -0
- data/tests/expected/readme-bmbm.txt +3 -0
- data/tests/expected/readme-simple.txt +4 -0
- data/tests/expected/script-bips.txt +18 -0
- data/tests/expected/script-bm.txt +3 -0
- data/tests/expected/script-bmbm.txt +3 -0
- data/tests/expected/script-simple.txt +4 -0
- data/tests/rewritten/mri.rb +15 -0
- data/tests/tests.rb +73 -0
- data/tests/tools/squash.rb +63 -0
- metadata +130 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
class BenchmarkSet
|
11
|
+
|
12
|
+
attr_reader :iterations
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@benchmarks = []
|
16
|
+
@counter = 0
|
17
|
+
@@current = self
|
18
|
+
@iterations = 1
|
19
|
+
end
|
20
|
+
|
21
|
+
def load_benchmarks(path)
|
22
|
+
@path = path
|
23
|
+
@@current = self
|
24
|
+
load(path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_mri_benchmarks(path, options)
|
28
|
+
@path = path
|
29
|
+
@@current = self
|
30
|
+
Frontends::MRI.load_mri path, options
|
31
|
+
end
|
32
|
+
|
33
|
+
def register(name, code)
|
34
|
+
name = implicit_name unless name
|
35
|
+
@benchmarks.push Benchmark.new(name, code)
|
36
|
+
end
|
37
|
+
|
38
|
+
def implicit_name
|
39
|
+
file = File.basename(@path, '.rb')
|
40
|
+
@counter += 1
|
41
|
+
"#{file}:#{@counter}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def prepare
|
45
|
+
# Don't give benchmarks line numbers if there's only one
|
46
|
+
|
47
|
+
if @benchmarks.size == 1
|
48
|
+
@benchmarks.first.remove_line_numbers
|
49
|
+
end
|
50
|
+
|
51
|
+
# Give benchmarks iterations if needed
|
52
|
+
|
53
|
+
if @benchmarks.any?(&:needs_iterating?)
|
54
|
+
iterations = @benchmarks.map(&:iterations_for_one_second).min
|
55
|
+
|
56
|
+
puts "This benchmark set contains blocks that want a number of iterations - running all iterations #{iterations} times"
|
57
|
+
|
58
|
+
@benchmarks.each do |b|
|
59
|
+
b.iterate iterations
|
60
|
+
end
|
61
|
+
|
62
|
+
@iterations = iterations
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def benchmarks(names=nil)
|
67
|
+
if names
|
68
|
+
@benchmarks.select { |b| names.include?(b.name) }
|
69
|
+
else
|
70
|
+
@benchmarks
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def benchmark(name)
|
75
|
+
benchmarks([name]).first
|
76
|
+
end
|
77
|
+
|
78
|
+
@@current = nil
|
79
|
+
|
80
|
+
def self.current
|
81
|
+
@@current
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
class Benchmark
|
11
|
+
|
12
|
+
attr_reader :name, :block
|
13
|
+
|
14
|
+
def initialize(name, block)
|
15
|
+
@name = name
|
16
|
+
@block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_line_numbers
|
20
|
+
@name = @name.split(':')[0...-1].join(':') if @name.include? ':'
|
21
|
+
end
|
22
|
+
|
23
|
+
def time_block(desired_time)
|
24
|
+
iterations = 1
|
25
|
+
while true
|
26
|
+
start = Time.now
|
27
|
+
if block.arity == 1
|
28
|
+
block.call iterations
|
29
|
+
else
|
30
|
+
iterations.times do
|
31
|
+
block.call
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
time = Time.now - start
|
36
|
+
return [time, iterations] if time >= desired_time
|
37
|
+
iterations *= 2
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def basic_iteration_time
|
42
|
+
time, iterations = time_block(0.1)
|
43
|
+
time / iterations.to_f
|
44
|
+
end
|
45
|
+
|
46
|
+
def iterations_for_one_second
|
47
|
+
_, iterations = time_block(1)
|
48
|
+
iterations
|
49
|
+
end
|
50
|
+
|
51
|
+
def needs_iterating?
|
52
|
+
@block.arity == 1
|
53
|
+
end
|
54
|
+
|
55
|
+
def iterate(iterations)
|
56
|
+
original_block = @block
|
57
|
+
|
58
|
+
if original_block.arity == 1
|
59
|
+
@block = Proc.new do
|
60
|
+
original_block.call iterations
|
61
|
+
end
|
62
|
+
else
|
63
|
+
@block = Proc.new do
|
64
|
+
iterations.times do
|
65
|
+
original_block.call
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
input = harness_input
|
10
|
+
|
11
|
+
unless harness_verify(harness_sample(input))
|
12
|
+
abort 'result was incorrect'
|
13
|
+
end
|
14
|
+
|
15
|
+
Object.instance_eval do
|
16
|
+
alias_method :user_harness_sample, :harness_sample
|
17
|
+
end
|
18
|
+
|
19
|
+
BenchmarkInterface.benchmark do
|
20
|
+
user_harness_sample input
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
input = micro_harness_input
|
10
|
+
|
11
|
+
SMALL_PRIME = 149
|
12
|
+
|
13
|
+
Object.instance_eval do
|
14
|
+
alias_method :user_micro_harness_sample, :micro_harness_sample
|
15
|
+
end
|
16
|
+
|
17
|
+
BenchmarkInterface.benchmark do
|
18
|
+
user_micro_harness_sample input
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
|
11
|
+
class BenchmarkContext
|
12
|
+
|
13
|
+
def report(name=nil, &block)
|
14
|
+
BenchmarkInterface.benchmark name, &block
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
module Benchmark
|
22
|
+
|
23
|
+
CAPTION = " user system total real\n"
|
24
|
+
FORMAT = "%10.6u %10.6y %10.6t %10.6r\n"
|
25
|
+
|
26
|
+
def self.measure(name=nil, &block)
|
27
|
+
BenchmarkInterface.benchmark name, &block
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.realtime(name=nil, &block)
|
31
|
+
BenchmarkInterface.benchmark name, &block
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.benchmark(caption='', label_width=nil, format=nil, *labels)
|
35
|
+
yield BenchmarkInterface::BenchmarkContext.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.realtime(name=nil, &block)
|
39
|
+
BenchmarkInterface.benchmark name, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.bm(label_width=0, *labels)
|
43
|
+
yield BenchmarkInterface::BenchmarkContext.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.bmbm(label_width=0)
|
47
|
+
yield BenchmarkInterface::BenchmarkContext.new
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
|
11
|
+
class BipsContext
|
12
|
+
|
13
|
+
attr_accessor :compare, :hold, :time, :warmup, :iterations
|
14
|
+
|
15
|
+
def config(options)
|
16
|
+
# Ignore
|
17
|
+
end
|
18
|
+
|
19
|
+
def compare!
|
20
|
+
# Ignore
|
21
|
+
end
|
22
|
+
|
23
|
+
def item(name=nil, code=nil, &block)
|
24
|
+
raise 'cannot have both a string and a block' if code && block
|
25
|
+
block = eval("Proc.new { #{code} }") if code
|
26
|
+
BenchmarkInterface.benchmark name, &block
|
27
|
+
end
|
28
|
+
alias_method :report, :item
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module Benchmark
|
35
|
+
|
36
|
+
def self.ips
|
37
|
+
yield BenchmarkInterface::BipsContext.new
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
module Frontends
|
11
|
+
module MRI
|
12
|
+
|
13
|
+
CACHE_FILE = 'mri-rewrite-cache.rb'
|
14
|
+
|
15
|
+
def self.load_mri(path, options)
|
16
|
+
if options['--use-cache']
|
17
|
+
load CACHE_FILE
|
18
|
+
else
|
19
|
+
require 'parser/current'
|
20
|
+
require 'unparser'
|
21
|
+
|
22
|
+
source = File.read(path)
|
23
|
+
buffer = Parser::Source::Buffer.new(source)
|
24
|
+
buffer.source = source
|
25
|
+
parser = Parser::CurrentRuby.new
|
26
|
+
ast = parser.parse(buffer)
|
27
|
+
|
28
|
+
abort "AST rooted at unexpected #{ast.type.inspect}" unless ast.type == :begin
|
29
|
+
last = ast.children.last
|
30
|
+
abort "Last statement #{last.type.inspect} unexpected" unless [:while, :block, :send, :lvasgn].include? last.type
|
31
|
+
|
32
|
+
assigns = {}
|
33
|
+
|
34
|
+
rewriter = Class.new(Parser::Rewriter) do
|
35
|
+
define_method :on_lvasgn do |node|
|
36
|
+
if node == last
|
37
|
+
on_node node
|
38
|
+
elsif node.children.last.type == :int
|
39
|
+
name = node.children.first
|
40
|
+
value = node.children.last.children.last
|
41
|
+
assigns[name] = value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
define_method :on_node do |node|
|
46
|
+
return unless node == last
|
47
|
+
|
48
|
+
assigns_source = ''
|
49
|
+
|
50
|
+
assigns.each do |name, value|
|
51
|
+
if node.to_s.include? "(lvar #{name.inspect})"
|
52
|
+
assigns_source += "#{name} = #{value}; "
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
insert_before node.location.expression, 'BenchmarkInterface.benchmark { ' + assigns_source
|
57
|
+
insert_after node.location.expression, ' }'
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :on_while, :on_node
|
61
|
+
alias_method :on_block, :on_node
|
62
|
+
alias_method :on_send, :on_node
|
63
|
+
end
|
64
|
+
|
65
|
+
rewriter = rewriter.new
|
66
|
+
rewritten = rewriter.rewrite(buffer, ast)
|
67
|
+
|
68
|
+
if options['--show-rewrite']
|
69
|
+
puts rewritten
|
70
|
+
end
|
71
|
+
|
72
|
+
if options['--cache']
|
73
|
+
File.write(CACHE_FILE, rewritten)
|
74
|
+
exit 1
|
75
|
+
else
|
76
|
+
Object.instance_eval rewritten
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
|
11
|
+
class PerferContext
|
12
|
+
|
13
|
+
def iterate(name, &block)
|
14
|
+
BenchmarkInterface.benchmark name, &block
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
module Perfer
|
22
|
+
|
23
|
+
def self.session(name)
|
24
|
+
yield BenchmarkInterface::PerferContext.new
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
|
2
|
+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
|
3
|
+
# redistribute it and/or modify it under the terms of the:
|
4
|
+
#
|
5
|
+
# Eclipse Public License version 1.0
|
6
|
+
# GNU General Public License version 2
|
7
|
+
# GNU Lesser General Public License version 2.1
|
8
|
+
|
9
|
+
module BenchmarkInterface
|
10
|
+
|
11
|
+
class RBenchContext
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@columns = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def format(options)
|
18
|
+
# Ignore
|
19
|
+
end
|
20
|
+
|
21
|
+
def column(name, options=nil)
|
22
|
+
singleton_class = (class << self; self end)
|
23
|
+
singleton_class.class_eval "def #{name}(&block); rbench_benchmark #{name.inspect}, block; end"
|
24
|
+
@columns.push name
|
25
|
+
end
|
26
|
+
|
27
|
+
def group(name)
|
28
|
+
@group_name = name
|
29
|
+
yield self
|
30
|
+
ensure
|
31
|
+
@group_name = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def report(name, &block)
|
35
|
+
if @columns.size == 0
|
36
|
+
BenchmarkInterface.benchmark name, &block
|
37
|
+
else
|
38
|
+
@report_name = name
|
39
|
+
instance_eval &block
|
40
|
+
end
|
41
|
+
ensure
|
42
|
+
@report_name = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def summary(title)
|
46
|
+
# Ignore
|
47
|
+
end
|
48
|
+
|
49
|
+
def rbench_benchmark(column_name, block)
|
50
|
+
name = [@group_name, @report_name, column_name].compact.join('-')
|
51
|
+
BenchmarkInterface.benchmark name, &block
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
module RBench
|
59
|
+
|
60
|
+
def self.run(count, &block)
|
61
|
+
BenchmarkInterface::RBenchContext.new.instance_eval &block
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|