bench_press 0.2.1 → 0.3.0

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.
@@ -0,0 +1,83 @@
1
+ Bench Press
2
+ ===========
3
+
4
+ Bench Press is a simple dsl around Ruby's Benchmark library.
5
+
6
+ Place the code you wish to benchmark inside of a measure block, run the
7
+ bench_press command and you'll get a markdown report containing your system
8
+ information and the realtime benchmark.
9
+
10
+ Additionally, benchmarks can be published to the
11
+ [Ruby Benchmark](http://rubybenchmark.com) via
12
+ `bench_press --publish benchmark.rb` command.
13
+
14
+ ### Creating a new benchmark
15
+
16
+ Use the `--new` flag to get started
17
+ $ bench_press --new benchmark
18
+ $ vi benchmark.rb
19
+
20
+ ## Example
21
+
22
+ # foo.rb
23
+ require 'bench_press'
24
+ extend BenchPress
25
+
26
+ base_string = ""
27
+ measure "string append" do
28
+ base_string << "Hello World"
29
+ end
30
+
31
+ base_string = ""
32
+ measure "string +=" do
33
+ base_string += "Hello World"
34
+ end
35
+
36
+ $ bench_press foo.rb
37
+
38
+ Foo
39
+ ===
40
+ Date: August 05, 2010
41
+
42
+ System Information
43
+ ------------------
44
+ Operating System: Mac OS X 10.6.4 (10F569)
45
+ CPU: Intel Core 2 Duo 2.4 GHz
46
+ Processor Count: 2
47
+ Memory: 4 GB
48
+ ruby 1.8.7 (2009-12-24 patchlevel 248) [i686-darwin10.2.0], MBARI 0x6770, Ruby Enterprise Edition 2010.01
49
+
50
+ "string append" is up to 71% faster over 1000 repetitions
51
+ ---------------------------------------------------------
52
+
53
+ string append 0.00270986557006836 secs Fastest
54
+ string += 0.00948691368103027 secs 71% Slower
55
+
56
+ ## Details
57
+ The default number of repetitions is 1000 meaning each measure block is run
58
+ 1000 times.
59
+
60
+ Each measure block is run in a forked subprocess in an attempt to isolate the
61
+ memory usage per measurement. As of 0.3.0, the benchmark is run twice, the
62
+ first run gets thrown away while the second run is added to the report.
63
+
64
+ ## Running the binary/examples locally
65
+ I use rubygems but this library is $LOAD_PATH friendly which means we need to
66
+ set up our own load path when playing locally.
67
+
68
+ Try sourcing the .dev file
69
+
70
+ $ source .dev
71
+
72
+ ## Note on Patches/Pull Requests
73
+ * Fork the project.
74
+ * Make your feature addition or bug fix.
75
+ * Add tests for it. This is important so I don't break it in a
76
+ future version unintentionally.
77
+ * Commit, do not mess with rakefile, version, or history.
78
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
79
+ * Send me a pull request. Bonus points for topic branches.
80
+
81
+ ## Copyright
82
+
83
+ Copyright (c) 2009 Sandro Turriate. See LICENSE for details.
@@ -2,6 +2,8 @@
2
2
 
3
3
  Sharable benchmarks
4
4
 
5
+ bench_press --help for options
6
+
5
7
  == Running the binary/examples locally
6
8
  I use rubygems but this library is $LOAD_PATH friendly which means we need to
7
9
  set up our own load path when playing locally.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -5,17 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bench_press}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Sandro Turriate"]
12
- s.date = %q{2010-08-01}
12
+ s.date = %q{2010-08-05}
13
13
  s.default_executable = %q{bench_press}
14
14
  s.description = %q{Sharable benchmarks}
15
15
  s.email = %q{sandro.turriate@gmail.com}
16
16
  s.executables = ["bench_press"]
17
17
  s.extra_rdoc_files = [
18
- "README.rdoc",
18
+ "README.markdown",
19
+ "README.rdoc",
19
20
  "TODO"
20
21
  ]
21
22
  s.files = [
@@ -25,11 +26,13 @@ Gem::Specification.new do |s|
25
26
  ".rvmrc",
26
27
  "Gemfile",
27
28
  "MIT-LICENSE",
29
+ "README.markdown",
28
30
  "README.rdoc",
29
31
  "Rakefile",
30
32
  "VERSION",
31
33
  "bench_press.gemspec",
32
34
  "bin/bench_press",
35
+ "examples/clearing_an_array.rb",
33
36
  "examples/compare_rr_to_rspec.rb",
34
37
  "examples/existence_of_method.rb",
35
38
  "examples/hash_merge.rb",
@@ -67,9 +70,10 @@ Gem::Specification.new do |s|
67
70
  "spec/bench_press_spec.rb",
68
71
  "spec/spec_helper.rb",
69
72
  "spec/support/measurable.rb",
70
- "examples/array_vs_string_concatenation.rb",
73
+ "examples/clearing_an_array.rb",
71
74
  "examples/compare_rr_to_rspec.rb",
72
75
  "examples/existence_of_method.rb",
76
+ "examples/foo.rb",
73
77
  "examples/hash_merge.rb",
74
78
  "examples/implicit_versus_explicit_return.rb",
75
79
  "examples/regexp_matching.rb",
@@ -0,0 +1,50 @@
1
+ require 'bench_press'
2
+
3
+ extend BenchPress
4
+
5
+ author 'Sandro Turriate'
6
+ date '2010-08-01'
7
+ summary "
8
+ What's the best way to clear out an array? Could be useful if you're storing
9
+ messages in an array like a buffer. How should you flush the buffer when
10
+ you're done with it?
11
+ "
12
+
13
+ reps 10_000
14
+
15
+ ARRAY = (1..1000).to_a.freeze
16
+
17
+ measure "Array#clear" do
18
+ a = ARRAY.dup
19
+ a.clear
20
+ end
21
+
22
+ measure "Array#replace" do
23
+ a = ARRAY.dup
24
+ a.replace []
25
+ end
26
+
27
+ measure "Assign the variable to a new array" do
28
+ a = ARRAY.dup
29
+ a = []
30
+ end
31
+
32
+ measure "Array#-" do
33
+ a = ARRAY.dup
34
+ a = a - a
35
+ end
36
+
37
+ measure "Array#delete_if" do
38
+ a = ARRAY.dup
39
+ a.delete_if {true}
40
+ end
41
+
42
+ measure "Array#drop" do
43
+ a = ARRAY.dup
44
+ a = a.drop(a.size)
45
+ end
46
+
47
+ measure "Array#shift(n)" do
48
+ a = ARRAY.dup
49
+ a.shift(a.size)
50
+ end
@@ -0,0 +1,12 @@
1
+ require 'bench_press'
2
+ extend BenchPress
3
+
4
+ base_string = ""
5
+ measure "string append" do
6
+ base_string << "Hello World"
7
+ end
8
+
9
+ base_string = ""
10
+ measure "string +=" do
11
+ base_string += "Hello World"
12
+ end
@@ -9,7 +9,7 @@ require 'bench_press/report'
9
9
  require 'bench_press/system_information'
10
10
 
11
11
  module BenchPress
12
- VERSION = '0.2.1'
12
+ VERSION = '0.3.0'
13
13
 
14
14
  autoload :RubyBenchmark, 'bench_press/ruby_benchmark'
15
15
 
@@ -30,11 +30,15 @@ module BenchPress
30
30
  @optparse ||= OptionParser.new do |opts|
31
31
  opts.banner = "Usage: bench_press [options] file_to_benchmark.rb"
32
32
 
33
+ opts.on( '-n', '--new', 'Create a new benchmark' ) do
34
+ options[:new] = true
35
+ end
36
+
33
37
  opts.on( '-p', '--publish', 'Publish the benchmark to http://rubybenchmark.com' ) do
34
38
  options[:publish] = true
35
39
  end
36
40
 
37
- opts.on('--email EMAIL', String, "Author email, defaults to #{git_email}") do |email|
41
+ opts.on('--email EMAIL', String, "Author email used when publishing, defaults to #{git_email}") do |email|
38
42
  options[:email] = email
39
43
  end
40
44
 
@@ -49,6 +53,8 @@ module BenchPress
49
53
  exit_with_version
50
54
  elsif file_exists?
51
55
  perform_bench_press
56
+ elsif options[:new]
57
+ new_bench_press
52
58
  else
53
59
  abort "Could not proceed, please supply the filename you wish to benchmark"
54
60
  end
@@ -88,5 +94,41 @@ module BenchPress
88
94
  abort "Email missing. Use bench_press --publish --email me@example.com file.rb"
89
95
  end
90
96
  end
97
+
98
+ def new_bench_press
99
+ if filename && File.exists?(file_path_with_rb)
100
+ abort "A file named #{filename} already exists"
101
+ else
102
+ File.open(file_path_with_rb, 'w') { |f| f.write(template) } unless file_exists?
103
+ end
104
+ end
105
+
106
+ def file_path_with_rb
107
+ file_path + '.rb'
108
+ end
109
+
110
+ def template
111
+ <<-TEMPLATE
112
+
113
+ require 'bench_press'
114
+
115
+ extend BenchPress
116
+
117
+ name 'gem1 vs. gem2'
118
+ author 'YOUR NAME'
119
+ date '#{Time.now.strftime('%Y-%m-%d')}'
120
+ summary "
121
+ Describe what you're benchmarking
122
+ "
123
+
124
+ reps 10_000 #number of repetitions
125
+
126
+ measure "Class#method" do
127
+ # code to be benchmarked
128
+ end
129
+
130
+ TEMPLATE
131
+ end
132
+
91
133
  end
92
134
  end
@@ -56,7 +56,7 @@ module BenchPress
56
56
  end
57
57
 
58
58
  def heading
59
- %("#{result.fastest.name}" is up to #{result.slowest.percent_slower}% faster over #{repetitions} repetitions)
59
+ %("#{result.fastest.name}" is up to #{result.slowest.percent_slower}% faster over #{formatted_number repetitions} repetitions)
60
60
  end
61
61
 
62
62
  def runnable_heading
@@ -103,7 +103,7 @@ module BenchPress
103
103
  def repetitions
104
104
  Runnable.repetitions
105
105
  end
106
-
106
+
107
107
  def row(*columns)
108
108
  row = spacer
109
109
  columns.each do |column|
@@ -115,6 +115,10 @@ module BenchPress
115
115
  def spacer
116
116
  ' ' * SPACING
117
117
  end
118
+
119
+ def formatted_number(number, delimiter = ',')
120
+ number.to_s.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
121
+ end
118
122
 
119
123
  def run_name(content)
120
124
  content.to_s.ljust(result.longest_name.size + SPACING)
@@ -25,10 +25,9 @@ module BenchPress
25
25
  def run
26
26
  r,w = IO.pipe
27
27
  fork do
28
+ run_it
28
29
  time = Benchmark.realtime do
29
- self.class.repetitions.times do |i|
30
- code_block.call(i)
31
- end
30
+ run_it
32
31
  end
33
32
  w.write time
34
33
  w.close_write
@@ -55,5 +54,13 @@ module BenchPress
55
54
  :fastest => fastest
56
55
  }
57
56
  end
57
+
58
+ protected
59
+
60
+ def run_it
61
+ self.class.repetitions.times do |i|
62
+ code_block.call(i)
63
+ end
64
+ end
58
65
  end
59
66
  end
@@ -38,7 +38,13 @@ describe BenchPress::Report do
38
38
  subject.date.should == custom_date
39
39
  end
40
40
  end
41
-
41
+
42
+ describe "#formatted_number" do
43
+ it "comma-separates a number" do
44
+ subject.send(:formatted_number, 1000000).should == "1,000,000"
45
+ end
46
+ end
47
+
42
48
  describe "#runnable_results" do
43
49
  let(:report) do
44
50
  r = BenchPress::Report.new
@@ -52,13 +58,13 @@ describe BenchPress::Report do
52
58
 
53
59
  it "displays a heading" do
54
60
  heading = <<-EOS
55
- "Implicit return" is up to 17% faster over 1000 repetitions
56
- -----------------------------------------------------------
61
+ "Implicit return" is up to 17% faster over 1,000 repetitions
62
+ ------------------------------------------------------------
57
63
  EOS
58
64
 
59
65
  report.send(:runnable_heading).should == heading.strip
60
66
  end
61
-
67
+
62
68
  it "displays the table of results" do
63
69
  table = <<-EOS
64
70
  Implicit return 0.00029 secs Fastest
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bench_press
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sandro Turriate
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-01 00:00:00 -04:00
18
+ date: 2010-08-05 00:00:00 -04:00
19
19
  default_executable: bench_press
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -105,6 +105,7 @@ executables:
105
105
  extensions: []
106
106
 
107
107
  extra_rdoc_files:
108
+ - README.markdown
108
109
  - README.rdoc
109
110
  - TODO
110
111
  files:
@@ -114,11 +115,13 @@ files:
114
115
  - .rvmrc
115
116
  - Gemfile
116
117
  - MIT-LICENSE
118
+ - README.markdown
117
119
  - README.rdoc
118
120
  - Rakefile
119
121
  - VERSION
120
122
  - bench_press.gemspec
121
123
  - bin/bench_press
124
+ - examples/clearing_an_array.rb
122
125
  - examples/compare_rr_to_rspec.rb
123
126
  - examples/existence_of_method.rb
124
127
  - examples/hash_merge.rb
@@ -142,7 +145,7 @@ files:
142
145
  - spec/spec_helper.rb
143
146
  - spec/support/measurable.rb
144
147
  - TODO
145
- - examples/array_vs_string_concatenation.rb
148
+ - examples/foo.rb
146
149
  has_rdoc: true
147
150
  homepage: http://github.com/sandro/bench_press
148
151
  licenses: []
@@ -186,9 +189,10 @@ test_files:
186
189
  - spec/bench_press_spec.rb
187
190
  - spec/spec_helper.rb
188
191
  - spec/support/measurable.rb
189
- - examples/array_vs_string_concatenation.rb
192
+ - examples/clearing_an_array.rb
190
193
  - examples/compare_rr_to_rspec.rb
191
194
  - examples/existence_of_method.rb
195
+ - examples/foo.rb
192
196
  - examples/hash_merge.rb
193
197
  - examples/implicit_versus_explicit_return.rb
194
198
  - examples/regexp_matching.rb
@@ -1,30 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__) + "/../lib")
2
- require 'bench_press'
3
-
4
- extend BenchPress
5
-
6
- reps 100_000
7
- array = []
8
- measure "Array#<<" do |repetition|
9
- array << "1234567890"
10
- end
11
-
12
- string = ""
13
- measure "String#<<" do |repetition|
14
- string << "1234567890"
15
- end
16
-
17
- a = (1..1000).to_a
18
- measure "Array#clear" do
19
- a.dup.clear
20
- end
21
-
22
- measure "Array#replace" do
23
- a.dup
24
- a.replace []
25
- end
26
-
27
- measure "Re-assigning to new array" do
28
- a.dup
29
- a = []
30
- end