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