benchmark_unit 0.0.1 → 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.tar.gz.sig +0 -0
- data/CHANGELOG +1 -1
- data/Manifest +1 -0
- data/README +38 -1
- data/benchmark_unit.gemspec +7 -7
- data/lib/benchmark/assertions.rb +44 -12
- data/lib/benchmark/float.rb +1 -0
- data/lib/benchmark/ruby_seconds.rb +24 -16
- data/lib/benchmark/unit.rb +6 -3
- data/lib/benchmark_unit.rb +2 -0
- data/test/unit/benchmark_unit_test.rb +40 -10
- metadata +4 -3
- metadata.gz.sig +2 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
|
2
|
-
v0.
|
2
|
+
v0.1. First release.
|
data/Manifest
CHANGED
data/README
CHANGED
@@ -1,10 +1,47 @@
|
|
1
1
|
|
2
2
|
benchmark_unit
|
3
3
|
|
4
|
-
|
4
|
+
Machine-independent benchmark assertions for your unit tests.
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
8
8
|
Copyright 2007 Cloudburst, LLC. See included LICENSE file.
|
9
9
|
|
10
10
|
The public certificate for this gem is at http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem.
|
11
|
+
|
12
|
+
== Features
|
13
|
+
|
14
|
+
* Test::Unit-compatible
|
15
|
+
* machine-independent measurement units
|
16
|
+
|
17
|
+
== Installation
|
18
|
+
|
19
|
+
sudo gem install benchmark_unit
|
20
|
+
|
21
|
+
== Usage
|
22
|
+
|
23
|
+
First, require the library. Then, in a regular Test::Unit::TestCase, call either <tt>assert_faster</tt> or <tt>assert_slower</tt>. Pass a number of RubySeconds and a block to benchmark.
|
24
|
+
|
25
|
+
require 'benchmark/unit'
|
26
|
+
|
27
|
+
class MyTest < Test::Unit::TestCase
|
28
|
+
|
29
|
+
def test_speed_of_critical_method
|
30
|
+
assert_faster(3) do
|
31
|
+
MyCriticalMethod("data")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
You do not have to manually run the block multiple times; the library does that for you.
|
38
|
+
|
39
|
+
To find how many RubySeconds to start with, just omit the argument to the <tt>assert_faster</tt> or <tt>assert_slower</tt> call. The test will fail and report how long your block took. Add a little bit and use that as your initial failure point.
|
40
|
+
|
41
|
+
See Benchmark::RubySeconds for more details.
|
42
|
+
|
43
|
+
== Reporting problems
|
44
|
+
|
45
|
+
* http://rubyforge.org/forum/forum.php?forum_id=20547
|
46
|
+
|
47
|
+
Patches and contributions are very welcome. Please note that contributors are required to assign copyright for their additions to Cloudburst, LLC.
|
data/benchmark_unit.gemspec
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Benchmark_unit-0.
|
2
|
+
# Gem::Specification for Benchmark_unit-0.1
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{benchmark_unit}
|
7
|
-
s.version = "0.
|
7
|
+
s.version = "0.1"
|
8
8
|
|
9
9
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.authors = ["Evan Weaver"]
|
13
13
|
s.date = %q{2008-01-08}
|
14
|
-
s.description = %q{
|
14
|
+
s.description = %q{Machine-independent benchmark assertions for your unit tests.}
|
15
15
|
s.email = %q{}
|
16
|
-
s.files = ["CHANGELOG", "lib/benchmark/assertions.rb", "lib/benchmark/float.rb", "lib/benchmark/ruby_seconds.rb", "lib/benchmark/unit.rb", "LICENSE", "Manifest", "README", "test/unit/benchmark_unit_test.rb", "benchmark_unit.gemspec"]
|
16
|
+
s.files = ["CHANGELOG", "lib/benchmark/assertions.rb", "lib/benchmark/float.rb", "lib/benchmark/ruby_seconds.rb", "lib/benchmark/unit.rb", "lib/benchmark_unit.rb", "LICENSE", "Manifest", "README", "test/unit/benchmark_unit_test.rb", "benchmark_unit.gemspec"]
|
17
17
|
s.has_rdoc = true
|
18
18
|
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/benchmark_unit/}
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
s.rubyforge_project = %q{fauna}
|
21
21
|
s.rubygems_version = %q{1.0.1}
|
22
|
-
s.summary = %q{
|
22
|
+
s.summary = %q{Machine-independent benchmark assertions for your unit tests.}
|
23
23
|
s.test_files = ["test/unit/benchmark_unit_test.rb"]
|
24
24
|
end
|
25
25
|
|
@@ -32,9 +32,9 @@ end
|
|
32
32
|
# Echoe.new("benchmark_unit") do |p|
|
33
33
|
# p.author = "Evan Weaver"
|
34
34
|
# p.project = "fauna"
|
35
|
-
# p.summary = "
|
35
|
+
# p.summary = "Machine-independent benchmark assertions for your unit tests."
|
36
36
|
# p.url = "http://blog.evanweaver.com/files/doc/fauna/benchmark_unit/"
|
37
37
|
# p.docs_host = 'blog.evanweaver.com:~/www/bax/public/files/doc/'
|
38
38
|
# p.require_signed = true
|
39
|
-
# p.test_pattern = ["
|
39
|
+
# p.test_pattern = ["test/**/*.rb"]
|
40
40
|
# end
|
data/lib/benchmark/assertions.rb
CHANGED
@@ -1,21 +1,29 @@
|
|
1
1
|
|
2
|
-
require 'test/unit
|
2
|
+
require 'test/unit'
|
3
3
|
|
4
|
-
module
|
4
|
+
module Benchmark #:nodoc:
|
5
5
|
module Unit
|
6
6
|
module Assertions
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
# Assert that the average execution time of the block is faster than the target number of RubySeconds (i.e., takes less time). Default target is 0 (everything fails).
|
9
|
+
def assert_faster(target = 0, &block)
|
10
|
+
clean_backtrace do
|
11
|
+
compare_benchmark(target, :faster, &block)
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
|
-
|
13
|
-
|
15
|
+
# Assert that the average execution time of the block is slower than the target number of RubySeconds (i.e., takes more time). Default target is Infinity (everything fails).
|
16
|
+
def assert_slower(target = 1/0.0, &block) # Infinity
|
17
|
+
clean_backtrace do
|
18
|
+
compare_benchmark(target, :slower, &block)
|
19
|
+
end
|
14
20
|
end
|
15
21
|
|
16
22
|
private
|
17
23
|
|
18
24
|
def compare_benchmark(target, operator)
|
25
|
+
raise unless [:faster, :slower].include? operator
|
26
|
+
|
19
27
|
time, multiplier = 0, 1
|
20
28
|
|
21
29
|
while (time < 0.01) do
|
@@ -39,15 +47,39 @@ module Test
|
|
39
47
|
end
|
40
48
|
|
41
49
|
time = total / iterations
|
42
|
-
message = "
|
50
|
+
message = "<#{time.inspect} RubySeconds> is not #{operator} than #{target.inspect} RubySeconds."
|
43
51
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
52
|
+
assert_block message do
|
53
|
+
if operator == :faster
|
54
|
+
time < target
|
55
|
+
elsif operator == :slower
|
56
|
+
time > target
|
57
|
+
end
|
48
58
|
end
|
59
|
+
|
49
60
|
end
|
50
|
-
|
61
|
+
|
62
|
+
# Strip our library files from the assertion backtrace.
|
63
|
+
def clean_backtrace(&block) #:nodoc:
|
64
|
+
# Modified from Rails' version
|
65
|
+
begin
|
66
|
+
yield
|
67
|
+
rescue Object => error
|
68
|
+
library_path = Regexp.new(
|
69
|
+
File.expand_path("#{File.dirname(__FILE__)}/(assertions|unit)") +
|
70
|
+
'|benchmark.rb.*measure'
|
71
|
+
)
|
72
|
+
error.backtrace.reject! { |line| File.expand_path(line) =~ library_path }
|
73
|
+
raise
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
51
77
|
end
|
52
78
|
end
|
53
79
|
end
|
80
|
+
|
81
|
+
#:stopdoc:
|
82
|
+
|
83
|
+
class Test::Unit::TestCase
|
84
|
+
include Benchmark::Unit::Assertions
|
85
|
+
end
|
data/lib/benchmark/float.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
|
2
|
-
module Benchmark
|
2
|
+
module Benchmark #:nodoc:
|
3
|
+
|
4
|
+
=begin rdoc
|
5
|
+
RubySeconds are a machine-independent time measurement derived from benchmarking your hardware on some typical Ruby code. A RubySecond should be consistent enough for testing purposes across most architectures--hopefully within a 1/2 order of magnitude.
|
6
|
+
|
7
|
+
To see what your machine's RubySecond is in clock-seconds, call Benchmark::RubySeconds.size.
|
8
|
+
=end
|
3
9
|
class RubySeconds
|
4
10
|
|
5
11
|
PRECISION = 0.05
|
6
12
|
|
7
|
-
|
13
|
+
attr_reader :value
|
8
14
|
|
9
|
-
# Create a RubySeconds object from
|
15
|
+
# Create a RubySeconds object from clock-seconds.
|
10
16
|
def initialize(seconds)
|
11
17
|
@value = seconds.to_f / RubySeconds.size
|
12
18
|
end
|
13
19
|
|
14
20
|
# Delegate to the float. Inheriting from Float doesn't work well.
|
15
|
-
def method_missing(*args)
|
21
|
+
def method_missing(*args) #:nodoc:
|
16
22
|
@value.send(*args)
|
17
23
|
end
|
18
24
|
|
19
|
-
def to_s
|
25
|
+
def to_s #:nodoc:
|
20
26
|
@value.to_s
|
21
27
|
end
|
22
28
|
|
23
29
|
class << self
|
24
30
|
|
25
|
-
#
|
26
|
-
def measure
|
27
|
-
Benchmark.measure do
|
28
|
-
4.times { quanta }
|
29
|
-
end.total / 4.0
|
30
|
-
end
|
31
|
-
|
32
|
-
# Approach a stable unit size and memoize it.
|
31
|
+
# Return the size of a single RubySecond in clock-seconds for this machine.
|
33
32
|
def size
|
34
33
|
@size ||= begin
|
35
34
|
last, size = 0, measure
|
35
|
+
# Gradually approach a stable unit size, up to PRECISION %
|
36
36
|
while (size < last or (size - last) / size > PRECISION) do
|
37
37
|
last, size = size, measure
|
38
38
|
end
|
@@ -40,12 +40,19 @@ module Benchmark
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
protected
|
44
|
+
|
45
|
+
# Measure the "standard" Ruby unit of time on this machine.
|
46
|
+
def measure
|
47
|
+
Benchmark.measure do
|
48
|
+
4.times { quanta }
|
49
|
+
end.total / 4.0
|
50
|
+
end
|
44
51
|
|
45
|
-
# Perform some
|
52
|
+
# Perform some typical Ruby operations.
|
46
53
|
def quanta
|
47
54
|
# Allocate things
|
48
|
-
array = [:symbol, "a = 3 if true", 2, Math::PI**2, "large string"*30] * 100
|
55
|
+
array = [[:symbol, "a = 3 if true", 2, Math::PI**2, "large string"*30]] * 100
|
49
56
|
# Re-assign
|
50
57
|
array.flatten!
|
51
58
|
# Process things with a closure
|
@@ -64,6 +71,7 @@ module Benchmark
|
|
64
71
|
recurse(20)
|
65
72
|
end
|
66
73
|
|
74
|
+
# Recurse <tt>i</tt> times.
|
67
75
|
def recurse(i)
|
68
76
|
recurse(i - 1) if i > 0
|
69
77
|
end
|
data/lib/benchmark/unit.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
|
2
2
|
require 'benchmark'
|
3
3
|
|
4
|
-
|
5
|
-
require '
|
4
|
+
if ENV['DEBUG']
|
5
|
+
require 'rubygems'
|
6
|
+
require 'ruby-debug'; Debugger.start
|
7
|
+
end
|
6
8
|
|
7
9
|
require 'benchmark/ruby_seconds'
|
8
10
|
require 'benchmark/assertions'
|
9
11
|
require 'benchmark/float'
|
10
12
|
|
11
|
-
module Benchmark
|
13
|
+
module Benchmark #:nodoc:
|
12
14
|
module Unit
|
13
15
|
|
14
16
|
CLOCK_TARGET = 2
|
15
17
|
|
18
|
+
# Measure a single run of a block in RubySeconds.
|
16
19
|
def self.measure
|
17
20
|
RubySeconds.new(
|
18
21
|
Benchmark.measure do
|
@@ -1,33 +1,63 @@
|
|
1
1
|
|
2
2
|
$LOAD_PATH << File.dirname(__FILE__) + "/../../lib"
|
3
3
|
|
4
|
+
# Test both requires
|
4
5
|
require 'benchmark/unit'
|
5
|
-
require '
|
6
|
+
require 'benchmark_unit'
|
6
7
|
|
7
|
-
|
8
|
+
STDERR.puts "RubySeconds.size is #{Benchmark::RubySeconds.size}" if ENV['DEBUG']
|
8
9
|
|
9
10
|
class BenchmarkUnitTest < Test::Unit::TestCase
|
10
11
|
|
11
12
|
def test_faster
|
12
|
-
assert_faster do
|
13
|
-
# Do nothing
|
14
|
-
end
|
15
13
|
assert_faster(3) do
|
16
14
|
"string" * 100
|
17
15
|
end
|
16
|
+
|
17
|
+
assert_raises Test::Unit::AssertionFailedError do
|
18
|
+
assert_faster do
|
19
|
+
# Do nothing
|
20
|
+
end
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
def test_slower
|
21
|
-
assert_slower do
|
22
|
-
"string" * 100
|
23
|
-
end
|
24
25
|
assert_slower(1.1) do
|
25
26
|
"string" * 30000000
|
26
27
|
end
|
27
|
-
|
28
|
+
|
29
|
+
assert_raises Test::Unit::AssertionFailedError do
|
30
|
+
assert_slower do
|
31
|
+
"string" * 3000
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# def test_sleep
|
37
|
+
# # Loops forever due to thread scheduling issues
|
38
|
+
# assert_slower(2) do
|
39
|
+
# sleep(3 * Benchmark::RubySeconds.size)
|
40
|
+
# end
|
41
|
+
# end
|
28
42
|
|
29
43
|
def test_failed_assertion_has_clean_backtrace
|
30
|
-
|
44
|
+
begin
|
45
|
+
assert_slower(3) do
|
46
|
+
"fast"
|
47
|
+
end
|
48
|
+
rescue Test::Unit::AssertionFailedError => e
|
49
|
+
assert e.backtrace.to_s !~ /compare_benchmark|benchmark.rb/
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_exception_has_clean_backtrace
|
54
|
+
begin
|
55
|
+
assert_faster(3) do
|
56
|
+
raise "o crap"
|
57
|
+
end
|
58
|
+
rescue RuntimeError => e
|
59
|
+
assert e.backtrace.to_s !~ /compare_benchmark|benchmark.rb/
|
60
|
+
end
|
31
61
|
end
|
32
62
|
|
33
63
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benchmark_unit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.1"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Weaver
|
@@ -34,7 +34,7 @@ date: 2008-01-08 00:00:00 -05:00
|
|
34
34
|
default_executable:
|
35
35
|
dependencies: []
|
36
36
|
|
37
|
-
description:
|
37
|
+
description: Machine-independent benchmark assertions for your unit tests.
|
38
38
|
email: ""
|
39
39
|
executables: []
|
40
40
|
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/benchmark/float.rb
|
49
49
|
- lib/benchmark/ruby_seconds.rb
|
50
50
|
- lib/benchmark/unit.rb
|
51
|
+
- lib/benchmark_unit.rb
|
51
52
|
- LICENSE
|
52
53
|
- Manifest
|
53
54
|
- README
|
@@ -78,6 +79,6 @@ rubyforge_project: fauna
|
|
78
79
|
rubygems_version: 1.0.1
|
79
80
|
signing_key:
|
80
81
|
specification_version: 2
|
81
|
-
summary:
|
82
|
+
summary: Machine-independent benchmark assertions for your unit tests.
|
82
83
|
test_files:
|
83
84
|
- test/unit/benchmark_unit_test.rb
|
metadata.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
��Dm��v "�t��ʄ�2xl�@�rb��E��.w�~`g��p��7.S�- |d#��/��%v�s@�fo-K��t���c��R]x
&�#XED�,�E>h�d6����V�1j�>����ns���
|
2
|
+
�5:�d������x��8�?���3��!����(��1#���t�����T���gC�e��u�X`�fE����<)TdžA�����������G{��K���g���xbLH �=��
|