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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +39 -0
  3. data/Gemfile +2 -0
  4. data/LICENCE +7 -0
  5. data/README.md +237 -0
  6. data/benchmark-interface.gemspec +20 -0
  7. data/bin/benchmark +15 -0
  8. data/examples/bench9000.rb +23 -0
  9. data/examples/bench9000micro.rb +31 -0
  10. data/examples/benchmark.rb +40 -0
  11. data/examples/bips.rb +34 -0
  12. data/examples/clamp.rb +17 -0
  13. data/examples/interface.rb +13 -0
  14. data/examples/long.rb +9 -0
  15. data/examples/mri.rb +15 -0
  16. data/examples/perfer.rb +25 -0
  17. data/examples/rbench.rb +46 -0
  18. data/examples/readme.rb +12 -0
  19. data/examples/script.rb +14 -0
  20. data/lib/benchmark-interface.rb +40 -0
  21. data/lib/benchmark-interface/backends/bench9000.rb +87 -0
  22. data/lib/benchmark-interface/backends/benchmark.rb +68 -0
  23. data/lib/benchmark-interface/backends/bips.rb +49 -0
  24. data/lib/benchmark-interface/backends/simple.rb +38 -0
  25. data/lib/benchmark-interface/benchmark-set.rb +85 -0
  26. data/lib/benchmark-interface/benchmark.rb +72 -0
  27. data/lib/benchmark-interface/frontends/bench9000.rb +21 -0
  28. data/lib/benchmark-interface/frontends/bench9000micro.rb +19 -0
  29. data/lib/benchmark-interface/frontends/benchmark.rb +50 -0
  30. data/lib/benchmark-interface/frontends/bips.rb +40 -0
  31. data/lib/benchmark-interface/frontends/mri.rb +84 -0
  32. data/lib/benchmark-interface/frontends/perfer.rb +27 -0
  33. data/lib/benchmark-interface/frontends/rbench.rb +64 -0
  34. data/lib/benchmark-interface/require.rb +38 -0
  35. data/lib/benchmark-interface/run.rb +111 -0
  36. data/lib/benchmark-interface/version.rb +13 -0
  37. data/tests/expected/bench9000-bips.txt +8 -0
  38. data/tests/expected/bench9000-bm.txt +2 -0
  39. data/tests/expected/bench9000-bmbm.txt +2 -0
  40. data/tests/expected/bench9000-simple.txt +2 -0
  41. data/tests/expected/bench9000micro-bips.txt +8 -0
  42. data/tests/expected/bench9000micro-bm.txt +2 -0
  43. data/tests/expected/bench9000micro-bmbm.txt +2 -0
  44. data/tests/expected/bench9000micro-simple.txt +2 -0
  45. data/tests/expected/benchmark-bips.txt +72 -0
  46. data/tests/expected/benchmark-bm.txt +12 -0
  47. data/tests/expected/benchmark-bmbm.txt +12 -0
  48. data/tests/expected/benchmark-simple.txt +22 -0
  49. data/tests/expected/bips-bips.txt +2 -0
  50. data/tests/expected/bips-bm.txt +7 -0
  51. data/tests/expected/bips-bmbm.txt +7 -0
  52. data/tests/expected/bips-simple.txt +11 -0
  53. data/tests/expected/interface-bips.txt +24 -0
  54. data/tests/expected/interface-bm.txt +4 -0
  55. data/tests/expected/interface-bmbm.txt +4 -0
  56. data/tests/expected/interface-simple.txt +6 -0
  57. data/tests/expected/long-bips.txt +9 -0
  58. data/tests/expected/long-bm.txt +2 -0
  59. data/tests/expected/long-bmbm.txt +2 -0
  60. data/tests/expected/long-simple.txt +2 -0
  61. data/tests/expected/mri-bips.txt +9 -0
  62. data/tests/expected/mri-bm.txt +2 -0
  63. data/tests/expected/mri-bmbm.txt +2 -0
  64. data/tests/expected/mri-simple.txt +2 -0
  65. data/tests/expected/perfer-bips.txt +20 -0
  66. data/tests/expected/perfer-bm.txt +4 -0
  67. data/tests/expected/perfer-bmbm.txt +4 -0
  68. data/tests/expected/perfer-simple.txt +5 -0
  69. data/tests/expected/rbench-bips.txt +42 -0
  70. data/tests/expected/rbench-bm.txt +7 -0
  71. data/tests/expected/rbench-bmbm.txt +7 -0
  72. data/tests/expected/rbench-simple.txt +12 -0
  73. data/tests/expected/readme-bips.txt +18 -0
  74. data/tests/expected/readme-bm.txt +3 -0
  75. data/tests/expected/readme-bmbm.txt +3 -0
  76. data/tests/expected/readme-simple.txt +4 -0
  77. data/tests/expected/script-bips.txt +18 -0
  78. data/tests/expected/script-bm.txt +3 -0
  79. data/tests/expected/script-bmbm.txt +3 -0
  80. data/tests/expected/script-simple.txt +4 -0
  81. data/tests/rewritten/mri.rb +15 -0
  82. data/tests/tests.rb +73 -0
  83. data/tests/tools/squash.rb +63 -0
  84. 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