baseline 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY ADDED
File without changes
@@ -0,0 +1,47 @@
1
+ baseline
2
+ ===========
3
+
4
+ (C) John Mair (banisterfiend) 2010
5
+
6
+ _arrange benchmarks into contexts_
7
+
8
+ * Install the [gem](https://rubygems.org/gems/baseline): `gem install baseline`
9
+ * Read the [documentation](http://rdoc.info/github/banister/baseline/master/file/README.md)
10
+ * See the [source code](http://github.com/banister/baseline)
11
+
12
+ Features and limitations
13
+ -------------------------
14
+
15
+ * Arranges benchmarks into contexts
16
+
17
+ Contact
18
+ -------
19
+
20
+ Problems or questions contact me at [github](http://github.com/banister)
21
+
22
+
23
+ License
24
+ -------
25
+
26
+ (The MIT License)
27
+
28
+ Copyright (c) 2011 John Mair (banisterfiend)
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining
31
+ a copy of this software and associated documentation files (the
32
+ 'Software'), to deal in the Software without restriction, including
33
+ without limitation the rights to use, copy, modify, merge, publish,
34
+ distribute, sublicense, and/or sell copies of the Software, and to
35
+ permit persons to whom the Software is furnished to do so, subject to
36
+ the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be
39
+ included in all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
42
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
45
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
46
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
47
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ dlext = Config::CONFIG['DLEXT']
2
+ direc = File.dirname(__FILE__)
3
+
4
+ begin
5
+ require 'bones'
6
+ rescue LoadError
7
+ abort '### Please install the "bones" gem ###'
8
+ end
9
+
10
+ PROJECT_NAME = "baseline"
11
+
12
+ require 'rake/clean'
13
+ require 'rake/gempackagetask'
14
+ require "#{direc}/lib/#{PROJECT_NAME}/version"
15
+
16
+ CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
17
+ CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
18
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
19
+ "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
20
+
21
+ def apply_spec_defaults(s)
22
+ s.name = PROJECT_NAME
23
+ s.summary = "FIX ME"
24
+ s.version = Baseline::VERSION
25
+ s.date = Time.now.strftime '%Y-%m-%d'
26
+ s.author = "John Mair (banisterfiend)"
27
+ s.email = 'jrmair@gmail.com'
28
+ s.description = s.summary
29
+ s.require_path = 'lib'
30
+ s.homepage = "http://banisterfiend.wordpress.com"
31
+ s.has_rdoc = 'yard'
32
+ s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
33
+ "test/*.rb", "HISTORY", "README.md", "Rakefile"]
34
+ end
35
+
36
+ desc "run tests"
37
+ task :test do
38
+ sh "bacon -k #{direc}/test/test.rb"
39
+ end
40
+
41
+ namespace :ruby do
42
+ spec = Gem::Specification.new do |s|
43
+ apply_spec_defaults(s)
44
+ s.platform = Gem::Platform::RUBY
45
+ end
46
+
47
+ Rake::GemPackageTask.new(spec) do |pkg|
48
+ pkg.need_zip = false
49
+ pkg.need_tar = false
50
+ end
51
+ end
52
+
53
+ desc "build all platform gems at once"
54
+ task :gems => [:clean, :rmgems, "ruby:gem"]
55
+
56
+ desc "remove all platform gems"
57
+ task :rmgems => ["ruby:clobber_package"]
58
+
59
+ desc "build and push latest gems"
60
+ task :pushgems => :gems do
61
+ chdir("#{direc}/pkg") do
62
+ Dir["*.gem"].each do |gemfile|
63
+ sh "gem push #{gemfile}"
64
+ end
65
+ end
66
+ end
67
+
68
+
@@ -0,0 +1,167 @@
1
+ # (C) John Mair (banisterfiend) 2011
2
+ # MIT License
3
+
4
+ direc = File.dirname(__FILE__)
5
+
6
+ require 'benchmark'
7
+ require "#{direc}/baseline/output_format"
8
+
9
+ module Baseline
10
+ TIME_MODE_DEFAULT = :total
11
+ REPEAT_DEFAULT = 1
12
+
13
+ @time_mode = TIME_MODE_DEFAULT
14
+ @repeat = REPEAT_DEFAULT
15
+ @output_format = OutputFormat.new
16
+
17
+ class << self
18
+ attr_accessor :time_mode, :output_format, :repeat
19
+ end
20
+
21
+ class BenchContext
22
+ attr_reader :total_time, :bench_count,
23
+ :subcontext_count, :repeat
24
+
25
+ def initialize(repeat, nest_level, before, after)
26
+ @repeat = repeat
27
+ @total_time = 0
28
+ @nest_level = nest_level
29
+ @before = Array(before).dup
30
+ @after = Array(after).dup
31
+ @results = {}
32
+ @bench_count = @subcontext_count = 0
33
+ end
34
+
35
+ def before(&block)
36
+ @before.push(block)
37
+ end
38
+
39
+ def after(&block)
40
+ @after.unshift(block)
41
+ end
42
+
43
+ def exec_hooks(hooks)
44
+ hooks.each do |b|
45
+ instance_eval(&b)
46
+ end
47
+ end
48
+
49
+ def wrap_with_hooks(options={}, &block)
50
+ exec_hooks(options[:before])
51
+ yield
52
+ exec_hooks(options[:after])
53
+ end
54
+
55
+ def time_mode
56
+ Baseline.time_mode
57
+ end
58
+
59
+ def output_format
60
+ Baseline.output_format
61
+ end
62
+
63
+ def exec_bench(name, new_repeat, &block)
64
+ repeat = new_repeat || @repeat
65
+ bm_block = proc { repeat.times { yield } }
66
+
67
+ time = 0
68
+ wrap_with_hooks(:before => @before, :after => @after) do
69
+ time = Benchmark.measure(&bm_block).send(time_mode)
70
+ @total_time += time
71
+ end
72
+
73
+ @results[name] = time
74
+ @bench_count += 1
75
+
76
+ [name, time, new_repeat, :with_own_block]
77
+ end
78
+
79
+ def show(bench_data, &block)
80
+ case bench_data.last
81
+ when :without_own_block
82
+ name, new_repeat = bench_data
83
+ show exec_bench(name, new_repeat, &block)
84
+ when :with_own_block
85
+ name, time, new_repeat = bench_data
86
+ output_format.bench_output(name, time, new_repeat, @repeat, @nest_level)
87
+ end
88
+ end
89
+
90
+ def bench(name, options={}, &block)
91
+
92
+ # if no block then assume block is provided by show method and
93
+ # pass along requisite data so show can do its thing
94
+ if !block_given?
95
+ [name, options[:repeat], :without_own_block]
96
+ else
97
+ exec_bench(name, options[:repeat], &block)
98
+ end
99
+ end
100
+
101
+ def context(name, options={}, &block)
102
+ return output_format.context_skip(name) if options[:skip]
103
+
104
+ repeat = options[:repeat] || @repeat
105
+
106
+ bc = BenchContext.new(repeat, @nest_level + 1, @before, @after)
107
+ bench_count = subcontext_count = 0
108
+ output_format.context_output_header(name, options[:repeat], @repeat, @nest_level)
109
+
110
+ @total_time += time = bc.tap do |v|
111
+ v.instance_eval(&block)
112
+ bench_count = v.bench_count
113
+ subcontext_count = v.subcontext_count
114
+ end.
115
+ total_time
116
+
117
+ output_format.context_output_footer(name, time, bench_count, subcontext_count, @nest_level)
118
+ @results[name] = time
119
+ @subcontext_count += 1
120
+ @total_time
121
+ end
122
+
123
+ def compare(bench1, bench2)
124
+ benches = [bench1, bench2]
125
+ winner, loser = benches.sort_by! { |v| @results[v] }
126
+ time_diff = @results[loser] - @results[winner]
127
+ time_ratio = @results[loser] / @results[winner].to_f
128
+
129
+ output_format.compare_output(winner, loser, time_diff, time_ratio, @nest_level)
130
+ end
131
+
132
+ def rank(*names)
133
+ ranking = names.sort_by! { |v| @results[v] }
134
+ output_format.rank_output(ranking, @nest_level)
135
+ end
136
+ end
137
+
138
+ module ObjectExtensions
139
+ private
140
+ def context(name, options={}, &block)
141
+ return output_format.top_level_context_skip(name) if options[:skip]
142
+
143
+ repeat = options[:repeat] || Baseline.repeat
144
+ time_mode = Baseline.time_mode
145
+ output_format = Baseline.output_format
146
+
147
+ output_format.top_level_context_output_header(name, options[:repeat], Baseline.repeat, 0)
148
+ bench_count = subcontext_count = 0
149
+
150
+ top_level_context_time = Baseline::BenchContext.new(repeat, 1, nil, nil).
151
+ tap do |v|
152
+ v.instance_eval(&block)
153
+ bench_count = v.bench_count
154
+ subcontext_count = v.subcontext_count
155
+ end.
156
+ total_time
157
+
158
+ output_format.context_output_footer(name, top_level_context_time, bench_count, subcontext_count, 0)
159
+
160
+ top_level_context_time
161
+ end
162
+ end
163
+ end
164
+
165
+ class Object
166
+ include Baseline::ObjectExtensions
167
+ end
@@ -0,0 +1,58 @@
1
+ module Baseline
2
+ class OutputFormat
3
+ def indenter(nest_level)
4
+ " " * 2 * nest_level
5
+ end
6
+
7
+ def bench_output(name, time, new_repeat, orig_repeat, nest_level)
8
+ repeat = new_repeat || orig_repeat
9
+ repeat_text = new_repeat ? "(repeat: #{repeat})" : ""
10
+ puts "#{indenter(nest_level)}#{name}: %0.2f seconds #{repeat_text}" % time
11
+ end
12
+
13
+ def context_output_header(name, new_repeat, orig_repeat, nest_level)
14
+ repeat = new_repeat || orig_repeat
15
+ repeat_text = new_repeat ? "(repeat: #{repeat})" : ""
16
+ puts "#{indenter(nest_level)}"
17
+ puts "#{indenter(nest_level)}Benching #{name}: #{repeat_text}"
18
+ end
19
+
20
+ def context_output_footer(name, time, bench_count, subcontext_count, nest_level)
21
+ puts "#{indenter(nest_level)}Total time: %0.2f seconds for #{name} " \
22
+ "[#{bench_count} benches and #{subcontext_count} subcontexts]" % time
23
+ puts "#{indenter(nest_level)}"
24
+ end
25
+
26
+ def context_skip(name)
27
+ puts "[Skipping #{name}]"
28
+ end
29
+
30
+ def top_level_context_skip(name)
31
+ puts "All Benchmarks disabled."
32
+ end
33
+
34
+ def top_level_context_output_header(name, new_repeat, orig_repeat, nest_level)
35
+ repeat = new_repeat || orig_repeat
36
+ time_mode = Baseline.time_mode
37
+ time_mode_text = time_mode != Baseline::TIME_MODE_DEFAULT ? "(time mode: #{time_mode})" : ""
38
+
39
+ repeat_text = new_repeat ? "(repeat: #{repeat})" : ""
40
+ puts "#{indenter(nest_level)}"
41
+ puts "#{indenter(nest_level)}Benching #{name}: #{repeat_text} #{time_mode_text}"
42
+ end
43
+
44
+ def rank_output(ranking, nest_level)
45
+ quoted_ranking = ranking.map.with_index { |v, i| "#{i + 1}. \"#{v}\"" }.join(", ")
46
+ puts "#{indenter(nest_level)}Rankings: #{quoted_ranking}"
47
+ end
48
+
49
+ def compare_output(winner, loser, time_diff, time_ratio, nest_level)
50
+ if time_diff != 0
51
+ puts "#{indenter(nest_level)}Comparison: \"#{winner}\" is faster than \"#{loser}\"" \
52
+ " by %0.2f seconds (%0.2f times faster)" % [time_diff, time_ratio]
53
+ else
54
+ puts "#{indenter(nest_level)}Comparison: \"#{winner}\" is the same speed as \"#{loser}\""
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Baseline
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,12 @@
1
+ direc = File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require "#{direc}/../lib/baseline"
5
+ require 'bacon'
6
+
7
+ puts "Testing baseline version #{Baseline::VERSION}..."
8
+ puts "Ruby version: #{RUBY_VERSION}"
9
+
10
+ describe Baseline do
11
+ end
12
+
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: baseline
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - John Mair (banisterfiend)
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-30 00:00:00 +13:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: FIX ME
22
+ email: jrmair@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/baseline/output_format.rb
31
+ - lib/baseline/version.rb
32
+ - lib/baseline.rb
33
+ - test/test.rb
34
+ - HISTORY
35
+ - README.md
36
+ - Rakefile
37
+ has_rdoc: yard
38
+ homepage: http://banisterfiend.wordpress.com
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.7
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: FIX ME
69
+ test_files: []
70
+