benchmark-interface 0.1

Sign up to get free protection for your applications and to get access to all the features.
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