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.
- data/README.markdown +83 -0
- data/README.rdoc +2 -0
- data/VERSION +1 -1
- data/bench_press.gemspec +8 -4
- data/examples/clearing_an_array.rb +50 -0
- data/examples/foo.rb +12 -0
- data/lib/bench_press.rb +1 -1
- data/lib/bench_press/cli.rb +43 -1
- data/lib/bench_press/report.rb +6 -2
- data/lib/bench_press/runnable.rb +10 -3
- data/spec/bench_press/report_spec.rb +10 -4
- metadata +11 -7
- data/examples/array_vs_string_concatenation.rb +0 -30
data/README.markdown
ADDED
@@ -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.
|
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bench_press.gemspec
CHANGED
@@ -5,17 +5,18 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bench_press}
|
8
|
-
s.version = "0.
|
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-
|
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.
|
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/
|
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
|
data/examples/foo.rb
ADDED
data/lib/bench_press.rb
CHANGED
data/lib/bench_press/cli.rb
CHANGED
@@ -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
|
data/lib/bench_press/report.rb
CHANGED
@@ -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)
|
data/lib/bench_press/runnable.rb
CHANGED
@@ -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
|
-
|
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
|
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:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
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/
|
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/
|
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
|