should_be_faster 0.0.1
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 +9 -0
- data/lib/should_be_faster.rb +103 -0
- data/spec/should_be_faster_spec.rb +67 -0
- metadata +65 -0
data/README
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'spec'
|
3
|
+
require 'spec/matchers'
|
4
|
+
|
5
|
+
def _benchmark(code, iter)
|
6
|
+
Benchmark.measure { iter.times { code.call } }
|
7
|
+
end
|
8
|
+
|
9
|
+
Spec::Matchers.define(:be_faster_than) do |rhs_code, options|
|
10
|
+
options ||= {}
|
11
|
+
options[:matcher] = self
|
12
|
+
options[:faster] = true
|
13
|
+
Spec::Matchers::BenchmarkComparison.new(rhs_code, options).benchmark_comparison
|
14
|
+
end
|
15
|
+
|
16
|
+
Spec::Matchers.define(:be_slower_than) do |rhs_code, options|
|
17
|
+
options ||= {}
|
18
|
+
options[:matcher] = self
|
19
|
+
options[:faster] = false
|
20
|
+
Spec::Matchers::BenchmarkComparison.new(rhs_code, options).benchmark_comparison
|
21
|
+
end
|
22
|
+
|
23
|
+
module Spec
|
24
|
+
module Matchers
|
25
|
+
class BenchmarkComparison
|
26
|
+
def initialize(rhs_code, options={})
|
27
|
+
@rhs_code = rhs_code
|
28
|
+
@options = options
|
29
|
+
@options[:iterations] ||= 100
|
30
|
+
@options[:factor] ||= 1
|
31
|
+
@options[:faster] = @options[:faster] ? true : false # I hate ||= not working with booleans
|
32
|
+
end
|
33
|
+
|
34
|
+
def benchmark_comparison
|
35
|
+
factor = @options[:factor]
|
36
|
+
iter = @options[:iterations]
|
37
|
+
matcher = @options[:matcher]
|
38
|
+
faster = @options[:faster]
|
39
|
+
rhs = _benchmark(@rhs_code, iter).real
|
40
|
+
lhs = nil
|
41
|
+
|
42
|
+
matcher.match do |lhs_code|
|
43
|
+
lhs = (_benchmark(lhs_code, iter).real * factor)
|
44
|
+
if faster
|
45
|
+
lhs < rhs
|
46
|
+
else
|
47
|
+
lhs > rhs
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
matcher.instance_eval do
|
52
|
+
failure_message_for_should do |actual|
|
53
|
+
if faster
|
54
|
+
"ran too slow: #{lhs / rhs}x, #{lhs - rhs}s"
|
55
|
+
else
|
56
|
+
"ran too fast: #{rhs / lhs}x, #{rhs - lhs}s"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
failure_message_for_should_not do |actual|
|
61
|
+
if faster
|
62
|
+
"ran too slow: #{rhs / lhs}x, #{rhs - lhs}s"
|
63
|
+
else
|
64
|
+
"ran too fast: #{lhs / rhs}x, #{lhs - rhs}s"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
description do
|
69
|
+
if faster
|
70
|
+
"be faster than #{rhs}"
|
71
|
+
else
|
72
|
+
"be slower than #{rhs}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class BePredicate < Be
|
80
|
+
def times
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def faster_than(rhs_code, options={})
|
85
|
+
Matcher.new(:faster_than) do
|
86
|
+
options ||= {}
|
87
|
+
options[:faster] = true
|
88
|
+
options[:matcher] = self
|
89
|
+
Spec::Matchers::BenchmarkComparison.new(rhs_code, options).benchmark_comparison
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def slower_than(rhs_code, options={})
|
94
|
+
Matcher.new(:slower_than) do
|
95
|
+
options ||= {}
|
96
|
+
options[:faster] = false
|
97
|
+
options[:matcher] = self
|
98
|
+
Spec::Matchers::BenchmarkComparison.new(rhs_code, options).benchmark_comparison
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'lib/should_be_faster'
|
2
|
+
|
3
|
+
describe 'should_be_faster' do
|
4
|
+
it 'should default to 100 iterations' do
|
5
|
+
options = mock('hash')
|
6
|
+
options.stub!(:[]).and_return(nil)
|
7
|
+
options.stub!(:[]=)
|
8
|
+
options.should_receive(:[]=).with(:iterations, 100)
|
9
|
+
Spec::Matchers::BenchmarkComparison.new(nil, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should take an options hash to specify iterations' do
|
13
|
+
options = mock('hash')
|
14
|
+
options.stub!(:[])
|
15
|
+
options.stub!(:[]=)
|
16
|
+
options.stub!(:[]).with(:iterations).and_return(20)
|
17
|
+
Spec::Matchers::BenchmarkComparison.new(nil, options)
|
18
|
+
options[:iterations].should == 20
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when ensuring code is' do
|
22
|
+
before do
|
23
|
+
@fast = lambda { [1, 2, 3, 4, 5, 6, 7, 8, 9].sort }
|
24
|
+
@slow = lambda { 100.times.map { rand } }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'faster_than' do
|
28
|
+
it 'should ensure lhs < rhs' do
|
29
|
+
@fast.should be_faster_than(@slow)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should ensure lhs !> rhs' do
|
33
|
+
@slow.should_not be_faster_than(@fast)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'slower_than' do
|
38
|
+
it 'should ensure lhs > rhs' do
|
39
|
+
@slow.should be_slower_than(@fast)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should ensure lhs !< rhs' do
|
43
|
+
@fast.should_not be_slower_than(@slow)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'at_least(x).times.faster_than' do
|
48
|
+
it 'should ensure lhs < rhs' do
|
49
|
+
@fast.should be_at_least(2).times.faster_than(@slow)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should ensure lhs !> rhs' do
|
53
|
+
@slow.should_not be_at_least(2).times.faster_than(@fast)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'at_least(x).times.slower_than' do
|
58
|
+
it 'should ensure lhs > rhs' do
|
59
|
+
@slow.should be_at_least(2).times.slower_than(@fast)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should ensure lhs !< rhs' do
|
63
|
+
@fast.should_not be_at_least(2).times.slower_than(@slow)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: should_be_faster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Turnbull
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-16 00:00:00 +11:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: dsturnbull@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README
|
33
|
+
files:
|
34
|
+
- lib/should_be_faster.rb
|
35
|
+
- README
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/dsturnbull/should_be_faster
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.3.5
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: provides rspec matcher to do simple benchmark tests
|
64
|
+
test_files:
|
65
|
+
- spec/should_be_faster_spec.rb
|