bench_press 0.1.3 → 0.2.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/.dev +3 -0
- data/.gitignore +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/bench_press.gemspec +32 -13
- data/bin/bench_press +1 -32
- data/examples/compare_rr_to_rspec.rb +8 -1
- data/examples/existence_of_method.rb +1 -1
- data/examples/hash_merge.rb +3 -4
- data/examples/implicit_versus_explicit_return.rb +3 -0
- data/examples/regexp_matching.rb +19 -0
- data/lib/bench_press.rb +32 -13
- data/lib/bench_press/cli.rb +91 -0
- data/lib/bench_press/report.rb +33 -18
- data/lib/bench_press/result.rb +1 -0
- data/lib/bench_press/ruby_benchmark.rb +31 -0
- data/lib/bench_press/runnable.rb +34 -4
- data/spec/bench_press/report_spec.rb +22 -10
- data/spec/bench_press/ruby_benchmark_spec.rb +41 -0
- data/spec/bench_press/runnable_spec.rb +31 -0
- data/spec/bench_press_spec.rb +25 -15
- data/spec/spec_helper.rb +13 -0
- data/spec/support/measurable.rb +17 -0
- metadata +66 -9
data/.dev
ADDED
data/.gitignore
CHANGED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm gemset use bench_press
|
data/Gemfile
ADDED
data/Rakefile
CHANGED
@@ -10,9 +10,11 @@ begin
|
|
10
10
|
gem.email = "sandro.turriate@gmail.com"
|
11
11
|
gem.homepage = "http://github.com/sandro/bench_press"
|
12
12
|
gem.authors = ["Sandro Turriate"]
|
13
|
-
gem.add_dependency "facter", "1.5.7"
|
14
|
-
gem.add_dependency "activesupport", "2.3.5"
|
13
|
+
gem.add_dependency "facter", ">=1.5.7"
|
14
|
+
gem.add_dependency "activesupport", ">=2.3.5"
|
15
|
+
gem.add_dependency "httparty", ">=0.6.1"
|
15
16
|
gem.add_development_dependency "rspec", "1.3.0"
|
17
|
+
gem.add_development_dependency "ephemeral_response", ">=0.3.1"
|
16
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
19
|
end
|
18
20
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/bench_press.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bench_press}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.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-
|
12
|
+
s.date = %q{2010-07-31}
|
13
13
|
s.default_executable = %q{bench_press}
|
14
14
|
s.description = %q{Sharable benchmarks}
|
15
15
|
s.email = %q{sandro.turriate@gmail.com}
|
@@ -19,8 +19,11 @@ Gem::Specification.new do |s|
|
|
19
19
|
"TODO"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
|
-
".
|
22
|
+
".dev",
|
23
|
+
".document",
|
23
24
|
".gitignore",
|
25
|
+
".rvmrc",
|
26
|
+
"Gemfile",
|
24
27
|
"MIT-LICENSE",
|
25
28
|
"README.rdoc",
|
26
29
|
"Rakefile",
|
@@ -31,53 +34,69 @@ Gem::Specification.new do |s|
|
|
31
34
|
"examples/existence_of_method.rb",
|
32
35
|
"examples/hash_merge.rb",
|
33
36
|
"examples/implicit_versus_explicit_return.rb",
|
37
|
+
"examples/regexp_matching.rb",
|
34
38
|
"lib/bench_press.rb",
|
39
|
+
"lib/bench_press/cli.rb",
|
35
40
|
"lib/bench_press/report.rb",
|
36
41
|
"lib/bench_press/result.rb",
|
42
|
+
"lib/bench_press/ruby_benchmark.rb",
|
37
43
|
"lib/bench_press/runnable.rb",
|
38
44
|
"lib/bench_press/system_information.rb",
|
39
45
|
"spec/bench_press/report_spec.rb",
|
40
46
|
"spec/bench_press/result_spec.rb",
|
47
|
+
"spec/bench_press/ruby_benchmark_spec.rb",
|
48
|
+
"spec/bench_press/runnable_spec.rb",
|
41
49
|
"spec/bench_press/system_information_spec.rb",
|
42
50
|
"spec/bench_press_spec.rb",
|
43
51
|
"spec/spec.opts",
|
44
|
-
"spec/spec_helper.rb"
|
52
|
+
"spec/spec_helper.rb",
|
53
|
+
"spec/support/measurable.rb"
|
45
54
|
]
|
46
55
|
s.homepage = %q{http://github.com/sandro/bench_press}
|
47
56
|
s.rdoc_options = ["--charset=UTF-8"]
|
48
57
|
s.require_paths = ["lib"]
|
49
|
-
s.rubygems_version = %q{1.3.
|
58
|
+
s.rubygems_version = %q{1.3.7}
|
50
59
|
s.summary = %q{Sharable benchmarks}
|
51
60
|
s.test_files = [
|
52
61
|
"spec/bench_press/report_spec.rb",
|
53
62
|
"spec/bench_press/result_spec.rb",
|
63
|
+
"spec/bench_press/ruby_benchmark_spec.rb",
|
64
|
+
"spec/bench_press/runnable_spec.rb",
|
54
65
|
"spec/bench_press/system_information_spec.rb",
|
55
66
|
"spec/bench_press_spec.rb",
|
56
67
|
"spec/spec_helper.rb",
|
68
|
+
"spec/support/measurable.rb",
|
57
69
|
"examples/array_vs_string_concatenation.rb",
|
58
70
|
"examples/compare_rr_to_rspec.rb",
|
59
71
|
"examples/existence_of_method.rb",
|
60
72
|
"examples/hash_merge.rb",
|
61
|
-
"examples/implicit_versus_explicit_return.rb"
|
73
|
+
"examples/implicit_versus_explicit_return.rb",
|
74
|
+
"examples/regexp_matching.rb"
|
62
75
|
]
|
63
76
|
|
64
77
|
if s.respond_to? :specification_version then
|
65
78
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
66
79
|
s.specification_version = 3
|
67
80
|
|
68
|
-
if Gem::Version.new(Gem::
|
69
|
-
s.add_runtime_dependency(%q<facter>, ["
|
70
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
81
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
82
|
+
s.add_runtime_dependency(%q<facter>, [">= 1.5.7"])
|
83
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
84
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
|
71
85
|
s.add_development_dependency(%q<rspec>, ["= 1.3.0"])
|
86
|
+
s.add_development_dependency(%q<ephemeral_response>, [">= 0.3.1"])
|
72
87
|
else
|
73
|
-
s.add_dependency(%q<facter>, ["
|
74
|
-
s.add_dependency(%q<activesupport>, ["
|
88
|
+
s.add_dependency(%q<facter>, [">= 1.5.7"])
|
89
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
90
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
75
91
|
s.add_dependency(%q<rspec>, ["= 1.3.0"])
|
92
|
+
s.add_dependency(%q<ephemeral_response>, [">= 0.3.1"])
|
76
93
|
end
|
77
94
|
else
|
78
|
-
s.add_dependency(%q<facter>, ["
|
79
|
-
s.add_dependency(%q<activesupport>, ["
|
95
|
+
s.add_dependency(%q<facter>, [">= 1.5.7"])
|
96
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
97
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
80
98
|
s.add_dependency(%q<rspec>, ["= 1.3.0"])
|
99
|
+
s.add_dependency(%q<ephemeral_response>, [">= 0.3.1"])
|
81
100
|
end
|
82
101
|
end
|
83
102
|
|
data/bin/bench_press
CHANGED
@@ -1,35 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require 'optparse'
|
3
2
|
require 'bench_press'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
optparse = OptionParser.new do |opts|
|
8
|
-
opts.banner = "Usage: bench_press [options] file_to_benchmark.rb"
|
9
|
-
|
10
|
-
opts.on( '-p', '--publish', 'Publish the benchmark to http://rubybenchmark.com' ) do
|
11
|
-
options[:publish] = true
|
12
|
-
end
|
13
|
-
|
14
|
-
opts.on( '-v', '--version', 'Show the version of bench_press' ) do
|
15
|
-
options[:version] = true
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
optparse.parse!
|
20
|
-
|
21
|
-
if options[:version]
|
22
|
-
puts BenchPress::VERSION
|
23
|
-
exit
|
24
|
-
end
|
25
|
-
|
26
|
-
filename = ARGV.first
|
27
|
-
abort "You must supply a filename that you want to benchmark." if filename.nil?
|
28
|
-
|
29
|
-
file = File.join(Dir.pwd, ARGV.first)
|
30
|
-
if File.exists?(file)
|
31
|
-
$0 = file
|
32
|
-
load file
|
33
|
-
else
|
34
|
-
abort "The file #{file} does not exist."
|
35
|
-
end
|
4
|
+
BenchPress::CLI.new(ARGV.dup).run
|
@@ -7,6 +7,12 @@ require 'bench_press'
|
|
7
7
|
module CompareRRToRspec
|
8
8
|
extend BenchPress
|
9
9
|
|
10
|
+
name 'Compare RR mocking to Rspec'
|
11
|
+
author 'Sandro Turriate'
|
12
|
+
summary "Ported from the [benchmarks](http://github.com/btakita/rr/tree/master/benchmarks/) directory within the [rr](http://github.com/btakita/rr) project. Repetition really matters in this example as Rspec is much faster sub 100 repetitions."
|
13
|
+
date '2009-08-03'
|
14
|
+
|
15
|
+
reps 1200
|
10
16
|
rspec_object = Object.new
|
11
17
|
rr_object = Object.new
|
12
18
|
|
@@ -14,6 +20,7 @@ module CompareRRToRspec
|
|
14
20
|
rspec_object.should_receive(:foobar).and_return("baz")
|
15
21
|
rspec_object.foobar
|
16
22
|
end
|
23
|
+
|
17
24
|
measure("rr mock") do
|
18
25
|
RR.mock(rr_object).foobar.returns("baz")
|
19
26
|
rr_object.foobar
|
@@ -21,4 +28,4 @@ module CompareRRToRspec
|
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
24
|
-
CompareRRToRspec.bench_press
|
31
|
+
puts CompareRRToRspec.bench_press
|
data/examples/hash_merge.rb
CHANGED
@@ -3,6 +3,9 @@ require 'bench_press'
|
|
3
3
|
|
4
4
|
extend BenchPress
|
5
5
|
|
6
|
+
author 'Sandro Turriate'
|
7
|
+
summary "Is merging the fastest way to store values into a hash?"
|
8
|
+
|
6
9
|
reps 30_000
|
7
10
|
|
8
11
|
measure "Hash#merge" do
|
@@ -13,10 +16,6 @@ measure "Hash#merge!" do
|
|
13
16
|
{}.merge!(:key => :value)
|
14
17
|
end
|
15
18
|
|
16
|
-
measure "Hash#store" do
|
17
|
-
{}.store(:key, :value)
|
18
|
-
end
|
19
|
-
|
20
19
|
measure "Hash#[]=" do
|
21
20
|
{}.[]=(:key, :value)
|
22
21
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + "/../lib")
|
2
|
+
require 'bench_press'
|
3
|
+
|
4
|
+
extend BenchPress
|
5
|
+
|
6
|
+
author 'Sandro Turriate'
|
7
|
+
summary %(
|
8
|
+
Ported from James Golick's [gist](https://gist.github.com/335639/81d140ebc1577a917cf70cf5d1ed73c777a1b3bd) wherein we compare the `=~` operator to the `String#match` method.
|
9
|
+
)
|
10
|
+
|
11
|
+
reps 1000
|
12
|
+
|
13
|
+
measure "String#match" do
|
14
|
+
"abcdefg".match /a/
|
15
|
+
end
|
16
|
+
|
17
|
+
measure "=~" do
|
18
|
+
"abcdefg" =~ /a/
|
19
|
+
end
|
data/lib/bench_press.rb
CHANGED
@@ -2,18 +2,31 @@ require 'active_support/inflector'
|
|
2
2
|
require 'date'
|
3
3
|
require 'benchmark'
|
4
4
|
require 'facter'
|
5
|
+
require 'bench_press/cli'
|
5
6
|
require 'bench_press/runnable'
|
6
7
|
require 'bench_press/result'
|
7
8
|
require 'bench_press/report'
|
8
9
|
require 'bench_press/system_information'
|
9
10
|
|
10
11
|
module BenchPress
|
11
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.2.0'
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
autoload :RubyBenchmark, 'bench_press/ruby_benchmark'
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_reader :current
|
18
|
+
|
19
|
+
attr_accessor :run_at_exit
|
20
|
+
alias run_at_exit? run_at_exit
|
21
|
+
|
22
|
+
def extended(base)
|
23
|
+
base.instance_variable_set(:@module_name, base.to_s) if base.is_a?(Module)
|
24
|
+
@current = base
|
25
|
+
end
|
15
26
|
end
|
16
27
|
|
28
|
+
@run_at_exit = true
|
29
|
+
|
17
30
|
def module_name
|
18
31
|
@module_name
|
19
32
|
end
|
@@ -26,13 +39,15 @@ module BenchPress
|
|
26
39
|
@report ||= Report.new report_name
|
27
40
|
end
|
28
41
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
42
|
+
def date(date)
|
43
|
+
report.date = Time.parse(date)
|
44
|
+
end
|
45
|
+
|
46
|
+
def name(new_report_name=nil)
|
47
|
+
if new_report_name
|
48
|
+
report.name = new_report_name
|
34
49
|
else
|
35
|
-
|
50
|
+
super()
|
36
51
|
end
|
37
52
|
end
|
38
53
|
|
@@ -44,6 +59,10 @@ module BenchPress
|
|
44
59
|
report.author = author
|
45
60
|
end
|
46
61
|
|
62
|
+
def email(email)
|
63
|
+
report.email = email
|
64
|
+
end
|
65
|
+
|
47
66
|
def reps(times)
|
48
67
|
Runnable.repetitions = times
|
49
68
|
end
|
@@ -54,17 +73,17 @@ module BenchPress
|
|
54
73
|
|
55
74
|
def bench_press
|
56
75
|
report.runnables = runnables
|
57
|
-
|
76
|
+
report
|
58
77
|
end
|
59
78
|
|
60
79
|
protected
|
61
80
|
|
62
81
|
def default_report_name
|
63
|
-
module_name ||
|
82
|
+
module_name || File.basename(calling_script, ".rb")
|
64
83
|
end
|
65
84
|
|
66
85
|
def report_name
|
67
|
-
|
86
|
+
ActiveSupport::Inflector.titleize default_report_name
|
68
87
|
end
|
69
88
|
|
70
89
|
def calling_script
|
@@ -73,5 +92,5 @@ module BenchPress
|
|
73
92
|
end
|
74
93
|
|
75
94
|
at_exit do
|
76
|
-
bench_press if respond_to?(:bench_press)
|
95
|
+
puts(bench_press) if respond_to?(:bench_press) && BenchPress.run_at_exit?
|
77
96
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module BenchPress
|
2
|
+
require 'optparse'
|
3
|
+
class CLI
|
4
|
+
attr_reader :argv, :options, :filename
|
5
|
+
|
6
|
+
def initialize(argv)
|
7
|
+
@argv = argv
|
8
|
+
@options = {}
|
9
|
+
optparse.parse!(argv)
|
10
|
+
@filename = argv.shift
|
11
|
+
end
|
12
|
+
|
13
|
+
def email
|
14
|
+
options[:email] || git_email
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_path
|
18
|
+
@file_path ||= File.join(Dir.pwd, filename)
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_exists?
|
22
|
+
filename && File.exists?(file_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_email
|
26
|
+
@git_email ||= %x(git config --global --get user.email).strip
|
27
|
+
end
|
28
|
+
|
29
|
+
def optparse
|
30
|
+
@optparse ||= OptionParser.new do |opts|
|
31
|
+
opts.banner = "Usage: bench_press [options] file_to_benchmark.rb"
|
32
|
+
|
33
|
+
opts.on( '-p', '--publish', 'Publish the benchmark to http://rubybenchmark.com' ) do
|
34
|
+
options[:publish] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('--email EMAIL', String, "Author email, defaults to #{git_email}") do |email|
|
38
|
+
options[:email] = email
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on( '-v', '--version', 'Show the version of bench_press' ) do
|
42
|
+
options[:version] = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def run
|
48
|
+
if options[:version]
|
49
|
+
exit_with_version
|
50
|
+
elsif file_exists?
|
51
|
+
perform_bench_press
|
52
|
+
else
|
53
|
+
abort "Could not proceed, please supply the filename you wish to benchmark"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def perform_bench_press
|
60
|
+
measurable.bench_press
|
61
|
+
if options[:publish]
|
62
|
+
publish
|
63
|
+
else
|
64
|
+
puts measurable.report
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def measurable
|
69
|
+
@measurable ||= begin
|
70
|
+
$0 = file_path
|
71
|
+
load file_path
|
72
|
+
BenchPress.run_at_exit = false
|
73
|
+
BenchPress.current
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def exit_with_version
|
78
|
+
puts BenchPress::VERSION
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
|
82
|
+
def publish
|
83
|
+
if email && email.any?
|
84
|
+
measurable.email email
|
85
|
+
RubyBenchmark.publish(measurable, file_path)
|
86
|
+
else
|
87
|
+
abort "Email missing. Use bench_press --publish --email me@example.com file.rb"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/bench_press/report.rb
CHANGED
@@ -2,17 +2,18 @@ module BenchPress
|
|
2
2
|
class Report
|
3
3
|
SPACING = 4
|
4
4
|
|
5
|
-
attr_accessor :runnables, :name, :summary, :author
|
5
|
+
attr_accessor :runnables, :name, :summary, :author, :date, :email
|
6
6
|
|
7
7
|
def initialize(name = "")
|
8
8
|
@name = name
|
9
9
|
end
|
10
10
|
|
11
11
|
def date
|
12
|
-
Date.today
|
12
|
+
@date ||= Date.today
|
13
13
|
end
|
14
14
|
|
15
15
|
def to_s
|
16
|
+
result
|
16
17
|
[
|
17
18
|
cover_page,
|
18
19
|
system_information,
|
@@ -21,6 +22,29 @@ module BenchPress
|
|
21
22
|
].join("\n\n")
|
22
23
|
end
|
23
24
|
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
result
|
28
|
+
{
|
29
|
+
:name => name,
|
30
|
+
:heading => heading,
|
31
|
+
:summary => summary,
|
32
|
+
:email => email,
|
33
|
+
:author => author,
|
34
|
+
:run_on => date,
|
35
|
+
:repetitions => repetitions,
|
36
|
+
:os => SystemInformation.os,
|
37
|
+
:cpu => SystemInformation.cpu,
|
38
|
+
:processor_count => SystemInformation.processor_count,
|
39
|
+
:memory => SystemInformation.memory,
|
40
|
+
:ruby_version => SystemInformation.ruby_version,
|
41
|
+
:report => to_s,
|
42
|
+
:runnables => runnables.map {|r| r.to_hash}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
24
48
|
def cover_page
|
25
49
|
[
|
26
50
|
header(name),
|
@@ -30,16 +54,17 @@ module BenchPress
|
|
30
54
|
].compact.join("\n")
|
31
55
|
end
|
32
56
|
|
57
|
+
def heading
|
58
|
+
%("#{result.fastest.name}" is up to #{result.slowest.percent_slower}% faster over #{repetitions} repetitions)
|
59
|
+
end
|
60
|
+
|
33
61
|
def runnable_heading
|
34
|
-
header(
|
35
|
-
%("#{result.fastest.name}" is up to #{result.slowest.percent_slower}% faster over #{repetitions} repetitions),
|
36
|
-
"-"
|
37
|
-
)
|
62
|
+
header(heading, "-")
|
38
63
|
end
|
39
64
|
|
40
65
|
def runnable_table
|
41
66
|
result.runnables.map do |r|
|
42
|
-
row(run_name(r.name), run_time(r.run_time),
|
67
|
+
row(run_name(r.name), run_time(r.run_time), r.summary)
|
43
68
|
end.join("\n")
|
44
69
|
end
|
45
70
|
|
@@ -50,14 +75,12 @@ module BenchPress
|
|
50
75
|
].join("\n")
|
51
76
|
end
|
52
77
|
|
53
|
-
protected
|
54
|
-
|
55
78
|
def announce_author
|
56
79
|
line("Author: #{author}") unless author.nil?
|
57
80
|
end
|
58
81
|
|
59
82
|
def announce_date
|
60
|
-
line("Date: #{date}") unless date.nil?
|
83
|
+
line("Date: #{date.strftime("%B %d, %Y")}") unless date.nil?
|
61
84
|
end
|
62
85
|
|
63
86
|
def announce_summary
|
@@ -96,14 +119,6 @@ module BenchPress
|
|
96
119
|
content.to_s.ljust(result.longest_name.size + SPACING)
|
97
120
|
end
|
98
121
|
|
99
|
-
def run_summary(r)
|
100
|
-
if r == result.fastest
|
101
|
-
"Fastest"
|
102
|
-
else
|
103
|
-
"#{r.percent_slower}% Slower"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
122
|
def run_time(secs)
|
108
123
|
secs.to_s.ljust(result.longest_run_time.size) + " secs" + spacer
|
109
124
|
end
|
data/lib/bench_press/result.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module BenchPress
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
class RubyBenchmark
|
5
|
+
include HTTParty
|
6
|
+
base_uri 'http://rubybenchmark.com'
|
7
|
+
|
8
|
+
def self.publish(measurable, file_path)
|
9
|
+
report = measurable.report.to_hash
|
10
|
+
report[:results_attributes] = report.delete(:runnables)
|
11
|
+
report.merge! :source => File.read(file_path)
|
12
|
+
new post("/reports", :body => {:report => report})
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :response
|
16
|
+
|
17
|
+
def initialize(response)
|
18
|
+
@response = response
|
19
|
+
end
|
20
|
+
|
21
|
+
def report_url
|
22
|
+
response.body if successful?
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def successful?
|
28
|
+
Net::HTTPSuccess === response.response
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/bench_press/runnable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module BenchPress
|
2
2
|
class Runnable
|
3
3
|
attr_reader :name, :code_block, :run_time
|
4
|
-
attr_accessor :percent_slower
|
4
|
+
attr_accessor :percent_slower, :fastest
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def repetitions
|
@@ -18,12 +18,42 @@ module BenchPress
|
|
18
18
|
@code_block = block
|
19
19
|
end
|
20
20
|
|
21
|
+
def fastest?
|
22
|
+
fastest == true
|
23
|
+
end
|
24
|
+
|
21
25
|
def run
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
r,w = IO.pipe
|
27
|
+
fork do
|
28
|
+
time = Benchmark.realtime do
|
29
|
+
self.class.repetitions.times do |i|
|
30
|
+
code_block.call(i)
|
31
|
+
end
|
25
32
|
end
|
33
|
+
w.write time
|
34
|
+
w.close_write
|
35
|
+
exit!
|
26
36
|
end
|
37
|
+
Process.waitall
|
38
|
+
w.close_write
|
39
|
+
@run_time = r.read.to_f
|
40
|
+
end
|
41
|
+
|
42
|
+
def summary
|
43
|
+
if fastest?
|
44
|
+
"Fastest"
|
45
|
+
else
|
46
|
+
"#{percent_slower}% Slower"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_hash
|
51
|
+
{
|
52
|
+
:name => name,
|
53
|
+
:run_time => run_time,
|
54
|
+
:summary => summary,
|
55
|
+
:fastest => fastest
|
56
|
+
}
|
27
57
|
end
|
28
58
|
end
|
29
59
|
end
|
@@ -27,6 +27,18 @@ describe BenchPress::Report do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
describe "#date" do
|
31
|
+
it "returns today's date" do
|
32
|
+
subject.date.should == Date.today
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns the custom date" do
|
36
|
+
custom_date = Time.parse('2010-01-01')
|
37
|
+
subject.date = custom_date
|
38
|
+
subject.date.should == custom_date
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
30
42
|
describe "#runnable_results" do
|
31
43
|
let(:report) do
|
32
44
|
r = BenchPress::Report.new
|
@@ -44,7 +56,7 @@ describe BenchPress::Report do
|
|
44
56
|
-----------------------------------------------------------
|
45
57
|
EOS
|
46
58
|
|
47
|
-
report.runnable_heading.should == heading.strip
|
59
|
+
report.send(:runnable_heading).should == heading.strip
|
48
60
|
end
|
49
61
|
|
50
62
|
it "displays the table of results" do
|
@@ -52,7 +64,7 @@ EOS
|
|
52
64
|
Implicit return 0.00029 secs Fastest
|
53
65
|
Explicit 0.00035 secs 17% Slower
|
54
66
|
EOS
|
55
|
-
report.runnable_table.should == table.chop
|
67
|
+
report.send(:runnable_table).should == table.chop
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
@@ -67,7 +79,7 @@ System Information
|
|
67
79
|
Memory: 4 GB
|
68
80
|
Ruby version: 1.8.7 patchlevel 174
|
69
81
|
EOS
|
70
|
-
subject.system_information.should == info.chop
|
82
|
+
subject.send(:system_information).should == info.chop
|
71
83
|
end
|
72
84
|
|
73
85
|
describe "#cover_page" do
|
@@ -84,34 +96,34 @@ System Information
|
|
84
96
|
end
|
85
97
|
|
86
98
|
it "displays the report name" do
|
87
|
-
report.cover_page.should include("Hash Merge\n==========")
|
99
|
+
report.send(:cover_page).should include("Hash Merge\n==========")
|
88
100
|
end
|
89
101
|
|
90
102
|
it "displays the report name and author name" do
|
91
|
-
report.cover_page.should include("Hash Merge\n==========\nAuthor: Sandro Turriate ")
|
103
|
+
report.send(:cover_page).should include("Hash Merge\n==========\nAuthor: Sandro Turriate ")
|
92
104
|
end
|
93
105
|
|
94
106
|
it "displays the report name, author name, and date" do
|
95
|
-
report.cover_page.should include("Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.
|
107
|
+
report.send(:cover_page).should include("Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.strftime("%B %d, %Y")} ")
|
96
108
|
end
|
97
109
|
|
98
110
|
it "displays the report name, author name, date, and summary" do
|
99
|
-
report.cover_page.should include("Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.
|
111
|
+
report.send(:cover_page).should include("Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.strftime("%B %d, %Y")} \nSummary: Various methods for appending to a hash ")
|
100
112
|
end
|
101
113
|
|
102
114
|
it "does not display the author when there is no author" do
|
103
115
|
report.stub(:author)
|
104
|
-
report.cover_page.should == "Hash Merge\n==========\nDate: #{date.
|
116
|
+
report.send(:cover_page).should == "Hash Merge\n==========\nDate: #{date.strftime("%B %d, %Y")} \nSummary: Various methods for appending to a hash "
|
105
117
|
end
|
106
118
|
|
107
119
|
it "does not display the summary when there is no summary" do
|
108
120
|
report.stub(:summary)
|
109
|
-
report.cover_page.should == "Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.
|
121
|
+
report.send(:cover_page).should == "Hash Merge\n==========\nAuthor: Sandro Turriate \nDate: #{date.strftime("%B %d, %Y")} "
|
110
122
|
end
|
111
123
|
|
112
124
|
it "only displays the date when author and summary are nil" do
|
113
125
|
report.stub(:summary => nil, :author => nil)
|
114
|
-
report.cover_page.should == "Hash Merge\n==========\nDate: #{date.
|
126
|
+
report.send(:cover_page).should == "Hash Merge\n==========\nDate: #{date.strftime("%B %d, %Y")} "
|
115
127
|
end
|
116
128
|
end
|
117
129
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BenchPress::RubyBenchmark do
|
4
|
+
let(:measurable) { Measurable.dup }
|
5
|
+
|
6
|
+
before do
|
7
|
+
BenchPress::RubyBenchmark.base_uri "http://localhost:3000"
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#report_url" do
|
11
|
+
subject do
|
12
|
+
BenchPress::RubyBenchmark.publish measurable, measurable.path
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when report is successfully created" do
|
16
|
+
before do
|
17
|
+
measurable.bench_press
|
18
|
+
Benchmark.stub(:realtime => 1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns the response body" do
|
22
|
+
subject.report_url.should =~ %r(http://localhost:3000/reports/\d+)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when creating the report is unsuccessful" do
|
27
|
+
before do
|
28
|
+
invalid_hash = {:runnables => {}}
|
29
|
+
measurable.report.stub(:to_hash => invalid_hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "has nil report url" do
|
33
|
+
subject.report_url.should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "contains error messages" do
|
37
|
+
subject.response.body.should include("can't be blank")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BenchPress::Runnable do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BenchPress::Runnable.new('fast method', lambda {})
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#summary" do
|
10
|
+
context "when fastest" do
|
11
|
+
before do
|
12
|
+
subject.stub(:fastest? => true)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "displays Fastest" do
|
16
|
+
subject.summary.should == "Fastest"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "not faster" do
|
21
|
+
before do
|
22
|
+
subject.stub(:fastest? => false)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "shows the percentage slower" do
|
26
|
+
subject.percent_slower = 25
|
27
|
+
subject.summary.should == "25% Slower"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/bench_press_spec.rb
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module TestModule
|
4
|
-
extend BenchPress
|
5
|
-
end
|
6
|
-
|
7
3
|
describe BenchPress do
|
8
4
|
describe "#default_report_name" do
|
9
5
|
it "is the name of the enclosing module" do
|
10
6
|
mod = Module.new do
|
11
|
-
def self.
|
7
|
+
def self.to_s
|
12
8
|
"ModuleName"
|
13
9
|
end
|
14
10
|
extend BenchPress
|
@@ -18,33 +14,47 @@ describe BenchPress do
|
|
18
14
|
|
19
15
|
it "is the name of the ruby script when the extending class has no name" do
|
20
16
|
mod = Module.new do
|
21
|
-
|
22
|
-
undef name
|
23
|
-
end
|
17
|
+
def self.to_s; nil; end
|
24
18
|
extend BenchPress
|
25
19
|
end
|
26
20
|
mod.stub(:calling_script => "bench_press.rb")
|
27
|
-
mod.send(:default_report_name).should == "
|
21
|
+
mod.send(:default_report_name).should == "bench_press"
|
28
22
|
end
|
29
23
|
end
|
30
24
|
|
31
25
|
describe "#name" do
|
32
26
|
it "sets the name of the report" do
|
33
|
-
|
27
|
+
Measurable.module_eval do
|
34
28
|
name "Foo versus Bar"
|
35
29
|
end
|
36
|
-
|
30
|
+
Measurable.report.name.should == "Foo versus Bar"
|
37
31
|
end
|
38
32
|
|
39
33
|
context "when no argument is provided" do
|
40
34
|
it "returns the module name when no argument is provided" do
|
41
|
-
|
35
|
+
Measurable.name.should == "Measurable"
|
42
36
|
end
|
43
37
|
|
44
|
-
it "
|
45
|
-
Module.
|
46
|
-
|
38
|
+
it "handles nil name" do
|
39
|
+
mod = Module.new do
|
40
|
+
def self.name; nil; end
|
41
|
+
extend BenchPress
|
42
|
+
end
|
43
|
+
mod.name.should be_nil
|
47
44
|
end
|
48
45
|
end
|
49
46
|
end
|
47
|
+
|
48
|
+
describe "#date" do
|
49
|
+
it "sets the report date to the passed in date" do
|
50
|
+
Measurable.date "2010/01/15"
|
51
|
+
Measurable.report.date.should == Time.parse("2010-01-15")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raises a parse error for bad dates" do
|
55
|
+
expect do
|
56
|
+
Measurable.date 1234
|
57
|
+
end.to raise_exception(TypeError)
|
58
|
+
end
|
59
|
+
end
|
50
60
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,20 @@ begin; require 'rubygems'; rescue LoadError; end
|
|
2
2
|
require 'bench_press'
|
3
3
|
require 'spec'
|
4
4
|
require 'spec/autorun'
|
5
|
+
require 'ephemeral_response'
|
5
6
|
|
7
|
+
Dir.glob("spec/support/*.rb") {|f| require f}
|
8
|
+
|
9
|
+
EphemeralResponse::Configuration.expiration = lambda do
|
10
|
+
one_day
|
11
|
+
end
|
6
12
|
|
7
13
|
Spec::Runner.configure do |config|
|
14
|
+
config.before(:suite) do
|
15
|
+
EphemeralResponse.activate
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after(:suite) do
|
19
|
+
EphemeralResponse.deactivate
|
20
|
+
end
|
8
21
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bench_press
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Sandro Turriate
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-07-31 00:00:00 -04:00
|
18
19
|
default_executable: bench_press
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: facter
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
|
-
- - "
|
27
|
+
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 5
|
@@ -35,9 +38,11 @@ dependencies:
|
|
35
38
|
name: activesupport
|
36
39
|
prerelease: false
|
37
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
38
42
|
requirements:
|
39
|
-
- - "
|
43
|
+
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 9
|
41
46
|
segments:
|
42
47
|
- 2
|
43
48
|
- 3
|
@@ -46,19 +51,53 @@ dependencies:
|
|
46
51
|
type: :runtime
|
47
52
|
version_requirements: *id002
|
48
53
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
54
|
+
name: httparty
|
50
55
|
prerelease: false
|
51
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 5
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 6
|
65
|
+
- 1
|
66
|
+
version: 0.6.1
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
52
74
|
requirements:
|
53
75
|
- - "="
|
54
76
|
- !ruby/object:Gem::Version
|
77
|
+
hash: 27
|
55
78
|
segments:
|
56
79
|
- 1
|
57
80
|
- 3
|
58
81
|
- 0
|
59
82
|
version: 1.3.0
|
60
83
|
type: :development
|
61
|
-
version_requirements: *
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: ephemeral_response
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 17
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
- 3
|
97
|
+
- 1
|
98
|
+
version: 0.3.1
|
99
|
+
type: :development
|
100
|
+
version_requirements: *id005
|
62
101
|
description: Sharable benchmarks
|
63
102
|
email: sandro.turriate@gmail.com
|
64
103
|
executables:
|
@@ -69,8 +108,11 @@ extra_rdoc_files:
|
|
69
108
|
- README.rdoc
|
70
109
|
- TODO
|
71
110
|
files:
|
111
|
+
- .dev
|
72
112
|
- .document
|
73
113
|
- .gitignore
|
114
|
+
- .rvmrc
|
115
|
+
- Gemfile
|
74
116
|
- MIT-LICENSE
|
75
117
|
- README.rdoc
|
76
118
|
- Rakefile
|
@@ -81,18 +123,25 @@ files:
|
|
81
123
|
- examples/existence_of_method.rb
|
82
124
|
- examples/hash_merge.rb
|
83
125
|
- examples/implicit_versus_explicit_return.rb
|
126
|
+
- examples/regexp_matching.rb
|
84
127
|
- lib/bench_press.rb
|
128
|
+
- lib/bench_press/cli.rb
|
85
129
|
- lib/bench_press/report.rb
|
86
130
|
- lib/bench_press/result.rb
|
131
|
+
- lib/bench_press/ruby_benchmark.rb
|
87
132
|
- lib/bench_press/runnable.rb
|
88
133
|
- lib/bench_press/system_information.rb
|
89
134
|
- spec/bench_press/report_spec.rb
|
90
135
|
- spec/bench_press/result_spec.rb
|
136
|
+
- spec/bench_press/ruby_benchmark_spec.rb
|
137
|
+
- spec/bench_press/runnable_spec.rb
|
91
138
|
- spec/bench_press/system_information_spec.rb
|
92
139
|
- spec/bench_press_spec.rb
|
93
140
|
- spec/spec.opts
|
94
141
|
- spec/spec_helper.rb
|
142
|
+
- spec/support/measurable.rb
|
95
143
|
- TODO
|
144
|
+
- examples/array_vs_string_concatenation.rb
|
96
145
|
has_rdoc: true
|
97
146
|
homepage: http://github.com/sandro/bench_press
|
98
147
|
licenses: []
|
@@ -103,34 +152,42 @@ rdoc_options:
|
|
103
152
|
require_paths:
|
104
153
|
- lib
|
105
154
|
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
106
156
|
requirements:
|
107
157
|
- - ">="
|
108
158
|
- !ruby/object:Gem::Version
|
159
|
+
hash: 3
|
109
160
|
segments:
|
110
161
|
- 0
|
111
162
|
version: "0"
|
112
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
113
165
|
requirements:
|
114
166
|
- - ">="
|
115
167
|
- !ruby/object:Gem::Version
|
168
|
+
hash: 3
|
116
169
|
segments:
|
117
170
|
- 0
|
118
171
|
version: "0"
|
119
172
|
requirements: []
|
120
173
|
|
121
174
|
rubyforge_project:
|
122
|
-
rubygems_version: 1.3.
|
175
|
+
rubygems_version: 1.3.7
|
123
176
|
signing_key:
|
124
177
|
specification_version: 3
|
125
178
|
summary: Sharable benchmarks
|
126
179
|
test_files:
|
127
180
|
- spec/bench_press/report_spec.rb
|
128
181
|
- spec/bench_press/result_spec.rb
|
182
|
+
- spec/bench_press/ruby_benchmark_spec.rb
|
183
|
+
- spec/bench_press/runnable_spec.rb
|
129
184
|
- spec/bench_press/system_information_spec.rb
|
130
185
|
- spec/bench_press_spec.rb
|
131
186
|
- spec/spec_helper.rb
|
187
|
+
- spec/support/measurable.rb
|
132
188
|
- examples/array_vs_string_concatenation.rb
|
133
189
|
- examples/compare_rr_to_rspec.rb
|
134
190
|
- examples/existence_of_method.rb
|
135
191
|
- examples/hash_merge.rb
|
136
192
|
- examples/implicit_versus_explicit_return.rb
|
193
|
+
- examples/regexp_matching.rb
|