bench_press 0.2.1 → 0.3.0

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