should_be_faster 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,9 @@
1
+ $ gem install should_be_faster
2
+
3
+ describe Benchmarkable do
4
+ it 'should be faster than the old crap code' do
5
+ old = lambda { 100.times.map { rand } }
6
+ new = lambda { true }
7
+ old.should be_at_least(10).times.slower_than(new)
8
+ end
9
+ end
@@ -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