automatthew-stevedore 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +57 -0
- data/Rakefile +3 -5
- data/examples/concat.rb +49 -0
- data/examples/instance_eval.rb +1 -3
- data/examples/stats_libs.rb +17 -15
- data/examples/variance.rb +64 -0
- data/lib/stevedore/class.rb +46 -7
- data/lib/stevedore/instance.rb +43 -29
- data/lib/stevedore/rsruby.rb +7 -20
- data/lib/stevedore/sample.rb +38 -0
- data/lib/stevedore/shell_r.rb +0 -2
- data/lib/stevedore/stats.rb +34 -23
- data/lib/stevedore.rb +4 -6
- data/stevedore.gemspec +7 -7
- data/test/helper.rb +1 -1
- data/test/test_sample.rb +7 -1
- metadata +12 -5
data/README
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
Stevedore is a tool for performing and comparing sets of benchmarks based on similar setup and teardown needs. Instances use their class's setup/teardown where available, and you can set or override these methods per instance.
|
2
|
+
|
3
|
+
Steve (and his subclasses, naturally) track any instances created and can run a comparison using Steve.compare_instances. If the R language is available, you can do a power analysis using the data from a trial run to suggest sample sizes and number of runs needed to meet certain figures of statistical reliability.
|
4
|
+
|
5
|
+
Steve uses the rsruby gem, if available, for basic stats and power analysis. As the rsruby gem uses a C extension, this could be problematic for non-MRI Rubys. In the absence of rsruby, stevedore uses bmarini-mathstats for the basic stats and attempts to shell out to R for power analysis (i.e. power.t.test)
|
6
|
+
|
7
|
+
|
8
|
+
class StringConcat < Stevedore
|
9
|
+
before_sample do
|
10
|
+
...
|
11
|
+
end
|
12
|
+
after_sample do
|
13
|
+
...
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
plus = StringConcat.new "Combining strings with +" do
|
18
|
+
measure do
|
19
|
+
10000.times do
|
20
|
+
"supercalifragilisticexpiali" + "docious"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
append = StringConcat.new "Combining strings with <<" do
|
26
|
+
measure do
|
27
|
+
10000.times do
|
28
|
+
"supercalifragilisticexpiali" << "docious"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
interpolate = StringConcat.new "Combining strings with interpolation" do
|
34
|
+
measure do
|
35
|
+
10000.times do
|
36
|
+
"supercalifragilisticexpiali#{'docious'}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
run_count, sample_size = 3, 8
|
42
|
+
|
43
|
+
puts "Measuring #{run_count} runs of #{sample_size} for each test."
|
44
|
+
StringConcat.run([append, interpolate], run_count, sample_size)
|
45
|
+
puts
|
46
|
+
StringConcat.report([append, interpolate]) => putses the following:
|
47
|
+
|
48
|
+
|
49
|
+
Combining strings
|
50
|
+
|
51
|
+
Mean Stddev Minimum Median Max
|
52
|
+
--------------------------------------------------------------------------------------
|
53
|
+
interpolating strings 0.003064 0.002386 0.001356 0.001682 0.008544
|
54
|
+
appending strings 0.009267 0.002933 0.005337 0.010756 0.013299
|
55
|
+
Ratio of means: 3.02487110476993
|
56
|
+
|
57
|
+
|
data/Rakefile
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Version = '0.1.0'
|
1
|
+
Version = '0.2.0'
|
4
2
|
|
5
3
|
task :default => [ :test ]
|
6
4
|
|
@@ -9,9 +7,9 @@ begin
|
|
9
7
|
require 'echoe'
|
10
8
|
Echoe.new('stevedore', Version) do |p|
|
11
9
|
p.project = 'stevedore'
|
12
|
-
p.summary = "Benchmarking with
|
10
|
+
p.summary = "Benchmarking framework with some statistickal stuff"
|
13
11
|
p.author = "Matthew King"
|
14
|
-
p.email = "automatthew
|
12
|
+
p.email = "self@automatthew.com"
|
15
13
|
p.ignore_pattern = /^(\.git).+/
|
16
14
|
p.test_pattern = "test/*.rb"
|
17
15
|
end
|
data/examples/concat.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
3
|
+
require 'stevedore'
|
4
|
+
|
5
|
+
class StringConcat < Steve
|
6
|
+
subject "Combining strings"
|
7
|
+
end
|
8
|
+
|
9
|
+
plus = StringConcat.new "plus" do
|
10
|
+
|
11
|
+
measure do
|
12
|
+
10000.times do
|
13
|
+
"supercalifragilisticexpiali" + "docious"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
append = StringConcat.new "appending strings" do
|
20
|
+
|
21
|
+
measure do
|
22
|
+
10000.times do
|
23
|
+
"supercalifragilisticexpiali" << "docious"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
interpolate = StringConcat.new "interpolating strings" do
|
30
|
+
|
31
|
+
measure do
|
32
|
+
10000.times do
|
33
|
+
"supercalifragilisticexpiali#{'docious'}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# append.load("append")
|
40
|
+
# interpolate.load("interpolate")
|
41
|
+
|
42
|
+
run_count, sample_size = 3, 8
|
43
|
+
|
44
|
+
puts "Measuring #{run_count} runs of #{sample_size} for each test."
|
45
|
+
StringConcat.run([append, interpolate], run_count, sample_size)
|
46
|
+
puts
|
47
|
+
StringConcat.report([append, interpolate])
|
48
|
+
append.dump
|
49
|
+
interpolate.dump
|
data/examples/instance_eval.rb
CHANGED
data/examples/stats_libs.rb
CHANGED
@@ -5,15 +5,20 @@ require 'rsruby'
|
|
5
5
|
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
6
6
|
require 'stevedore'
|
7
7
|
|
8
|
-
|
8
|
+
srand(2009)
|
9
|
+
array = (1..2000).to_a.map { |i| rand(800.0) }
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
rsruby = Stevedore.new "rsruby standard deviation" do
|
12
|
+
|
13
|
+
before do
|
14
|
+
@r = RSRuby.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
measure do
|
18
|
+
@r.sd(array)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
17
22
|
|
18
23
|
mathstats = Stevedore.new "mathstats standard deviation" do
|
19
24
|
|
@@ -23,19 +28,16 @@ mathstats = Stevedore.new "mathstats standard deviation" do
|
|
23
28
|
|
24
29
|
end
|
25
30
|
|
26
|
-
|
27
|
-
|
31
|
+
steve_stats = Stevedore.new "steve's own stats" do
|
28
32
|
before do
|
29
|
-
|
33
|
+
array.extend Stevedore::Stats
|
30
34
|
end
|
31
|
-
|
32
35
|
measure do
|
33
|
-
|
36
|
+
array.standard_deviation
|
34
37
|
end
|
35
|
-
|
36
38
|
end
|
37
39
|
|
38
40
|
|
39
|
-
Stevedore.compare_instances(5,
|
41
|
+
Stevedore.compare_instances(5, 25)
|
40
42
|
|
41
43
|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
3
|
+
require 'stevedore'
|
4
|
+
|
5
|
+
|
6
|
+
def variance_two_pass(array, mean)
|
7
|
+
n = array.size
|
8
|
+
denom = n - 1
|
9
|
+
variance = array.inject(0) {|memo, element| memo + (element - mean)**2 } / denom
|
10
|
+
end
|
11
|
+
|
12
|
+
def my_var(array, mean)
|
13
|
+
n = array.size
|
14
|
+
denom = n - 1
|
15
|
+
s = 0
|
16
|
+
array.each { |element| s = s + (element - mean)**2; }
|
17
|
+
s / denom
|
18
|
+
end
|
19
|
+
|
20
|
+
def for_var(array, mean)
|
21
|
+
n = array.size
|
22
|
+
denom = n - 1
|
23
|
+
s = 0
|
24
|
+
for element in array
|
25
|
+
s = s + (element - mean)**2
|
26
|
+
end
|
27
|
+
s / denom
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
class Variances < Steve
|
34
|
+
subject = "Calculating a statistical variance"
|
35
|
+
before do
|
36
|
+
srand(2009)
|
37
|
+
@array = (1..2000).to_a.map { |i| rand(800.0) }
|
38
|
+
s = 0; @array.each { |element| s = s + element }
|
39
|
+
@sum = s
|
40
|
+
@mean = @sum / @array.size.to_f
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
mathstats = Variances.new "bmarini-mathstats" do
|
46
|
+
measure do
|
47
|
+
@var = variance_two_pass(@array, @mean)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
no_inject = Variances.new "not using inject" do
|
52
|
+
measure do
|
53
|
+
@var = my_var(@array, @mean)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
for_loop = Variances.new "using for loop" do
|
58
|
+
measure do
|
59
|
+
@var = for_var(@array, @mean)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Variances.run_all( 8, 500)
|
64
|
+
Variances.report_all
|
data/lib/stevedore/class.rb
CHANGED
@@ -17,7 +17,11 @@ class Stevedore
|
|
17
17
|
val ? @delta = val : @delta ||= 0.001
|
18
18
|
end
|
19
19
|
|
20
|
+
def self.subject(val=nil)
|
21
|
+
@subject ||= val
|
22
|
+
end
|
20
23
|
|
24
|
+
# Heritable blocks for setup and measurement
|
21
25
|
def self.before(&block)
|
22
26
|
block ? @before = block : @before
|
23
27
|
end
|
@@ -42,28 +46,52 @@ class Stevedore
|
|
42
46
|
block ? @after_measure = block : @after_measure
|
43
47
|
end
|
44
48
|
|
45
|
-
def self.
|
46
|
-
|
47
|
-
@instances.each do |instance|
|
48
|
-
puts "'#{instance.name}'"
|
49
|
+
def self.run(instances, run_count, sample_size)
|
50
|
+
instances.each do |instance|
|
49
51
|
instance.go(run_count, sample_size)
|
50
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.run_all(run_count, sample_size)
|
56
|
+
run(@instances, run_count, sample_size)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.report_all
|
60
|
+
report(@instances)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.report(instances)
|
64
|
+
puts @subject if @subject
|
51
65
|
name_size = @instances.map { |i| i.name.size }.max
|
52
|
-
puts "\n%-#{name_size}s %12s %12s %12s %12s %12s" %
|
66
|
+
puts "\n%-#{name_size}s %12s %12s %12s %12s %12s" % ["", "Mean", "Stddev", "Minimum", "Median", "Max"]
|
53
67
|
puts "-" * (name_size + 5 * 13)
|
54
|
-
|
68
|
+
instances.sort_by { |i| i.mean }.each do |instance|
|
55
69
|
puts "%-#{name_size}s %12f %12f %12f %12f %12f" %
|
56
70
|
[ instance.name, instance.mean, instance.standard_deviation, instance.min, instance.median, instance.max]
|
57
71
|
end
|
72
|
+
means = instances.map { |i| i.mean }.sort
|
73
|
+
baseline = means.shift
|
74
|
+
diffs = means.map { |m| m / baseline }
|
75
|
+
puts "Ratio of means: #{diffs.join(', ')}"
|
58
76
|
puts
|
59
77
|
end
|
60
78
|
|
79
|
+
def self.compare_instances(run_count, sample_size)
|
80
|
+
puts
|
81
|
+
puts "Benchmark: #{@subject}" if @subject
|
82
|
+
puts
|
83
|
+
puts "Measuring #{run_count} runs of #{sample_size} for each test."
|
84
|
+
self.run_all(run_count, sample_size)
|
85
|
+
puts
|
86
|
+
self.report_all
|
87
|
+
end
|
88
|
+
|
61
89
|
# Run a small set of samples and use a power test to determine
|
62
90
|
# the optimal run count and sample size.
|
63
91
|
def self.recommend_test_size(run_count, sample_size)
|
64
92
|
puts "\nRunning trials (#{run_count} runs of #{sample_size}) for each instance.\n\n"
|
65
93
|
@instances.each do |instance|
|
66
|
-
|
94
|
+
puts "'#{instance.name}'"
|
67
95
|
instance.go(run_count, sample_size)
|
68
96
|
puts " Mean: %6f" % instance.mean
|
69
97
|
puts " Stddev: %6f" % instance.standard_deviation
|
@@ -83,4 +111,15 @@ class Stevedore
|
|
83
111
|
Stevedore::Stats.power_test(args)["n"].to_i
|
84
112
|
end
|
85
113
|
|
114
|
+
def self.calculated_power(n, d, std)
|
115
|
+
args = { :n => n, :delta => d, :sig_level => sig_level, :sd => std }
|
116
|
+
puts args.inspect
|
117
|
+
Stevedore::Stats.power_test(args)["power"]
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.calculated_delta(n, std)
|
121
|
+
args = { :n => n, :power => power, :sig_level => sig_level, :sd => std }
|
122
|
+
Stevedore::Stats.power_test(args)["delta"]
|
123
|
+
end
|
124
|
+
|
86
125
|
end
|
data/lib/stevedore/instance.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
class Stevedore
|
2
3
|
|
3
4
|
attr_accessor :name, :description, :samples
|
@@ -9,7 +10,7 @@ class Stevedore
|
|
9
10
|
@before_measure, @after_measure = klass.before_measure, klass.after_measure
|
10
11
|
@before_sample, @after_sample = klass.before_sample, klass.after_sample
|
11
12
|
@name, @description = name, description
|
12
|
-
@samples =
|
13
|
+
@samples = Sample.new
|
13
14
|
instance_eval( &block ) if block
|
14
15
|
end
|
15
16
|
|
@@ -18,10 +19,33 @@ class Stevedore
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def reset
|
21
|
-
@samples =
|
22
|
-
@
|
22
|
+
@samples = Sample.new
|
23
|
+
@flat = nil
|
23
24
|
end
|
24
25
|
|
26
|
+
def dump_path(name)
|
27
|
+
"stevedata/#{name.gsub(/\W+/, '_')}.yaml"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Dump sample data to file in YAML format
|
31
|
+
def dump(path=nil)
|
32
|
+
filename = ( path || dump_path(@name))
|
33
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
34
|
+
data = {}
|
35
|
+
@samples.each_with_index { |s, i| data[i] = s.to_a }
|
36
|
+
File.open filename, "w" do |f|
|
37
|
+
::YAML.dump(data, f)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def load(name)
|
42
|
+
filename = dump_path(name)
|
43
|
+
File.open(filename, 'r') do |f|
|
44
|
+
@samples = ::YAML.load(f)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
25
49
|
# Blocks for setup and measurement
|
26
50
|
|
27
51
|
def before(&block); @before = block; end
|
@@ -36,62 +60,52 @@ class Stevedore
|
|
36
60
|
|
37
61
|
def after_measure(&block); @after_measure = block; end
|
38
62
|
|
63
|
+
# Here you do the work you actually want to measure.
|
39
64
|
def measure(&block); @measure = block; end
|
40
65
|
|
41
66
|
def go(run_count, sample_size)
|
42
67
|
reset
|
43
68
|
instance_eval( &@before ) if @before
|
44
69
|
|
45
|
-
run_count.times do
|
46
|
-
sample =
|
70
|
+
run_count.times do
|
71
|
+
sample = Sample.new
|
47
72
|
instance_eval( &@before_sample ) if @before_sample
|
48
73
|
|
74
|
+
print "."; $stdout.flush
|
49
75
|
sample_size.times do
|
50
76
|
instance_eval( &@before_measure ) if @before_measure
|
51
|
-
|
52
|
-
|
53
|
-
|
77
|
+
|
78
|
+
sample << Benchmark.realtime { instance_eval( &@measure ) }
|
79
|
+
|
54
80
|
instance_eval( &@after_measure ) if @after_measure
|
55
81
|
end
|
56
|
-
|
57
82
|
instance_eval( &@after_sample ) if @after_sample
|
58
83
|
@samples << sample
|
59
84
|
end
|
60
|
-
|
85
|
+
puts; $stdout.flush
|
61
86
|
instance_eval( &@after ) if @after
|
62
87
|
end
|
63
88
|
|
64
89
|
def report
|
65
90
|
puts self.name
|
66
|
-
puts "#{run_count} sample runs, #{sample_size} measurements each"
|
67
91
|
puts " Mean: #{self.mean}"
|
68
92
|
puts " Standard deviation: #{self.standard_deviation}"
|
69
93
|
puts
|
70
94
|
end
|
71
95
|
|
72
|
-
def mean
|
73
|
-
self.flattened_samples.mean
|
74
|
-
end
|
96
|
+
def mean; @samples.mean; end
|
75
97
|
|
76
|
-
def median
|
77
|
-
self.flattened_samples.median
|
78
|
-
end
|
98
|
+
def median; @samples.median; end
|
79
99
|
|
80
|
-
def min
|
81
|
-
self.flattened_samples.min
|
82
|
-
end
|
100
|
+
def min; @samples.min; end
|
83
101
|
|
84
|
-
def max
|
85
|
-
self.flattened_samples.max
|
86
|
-
end
|
102
|
+
def max; @samples.max; end
|
87
103
|
|
88
|
-
def standard_deviation
|
89
|
-
self.flattened_samples.standard_deviation
|
90
|
-
end
|
104
|
+
def standard_deviation; @samples.standard_deviation; end
|
91
105
|
|
92
|
-
def sample_means
|
93
|
-
|
94
|
-
end
|
106
|
+
def sample_means; @samples.map { |s| s.mean }; end
|
107
|
+
|
108
|
+
def sample_sds; @samples.map { |s| s.standard_deviation }; end
|
95
109
|
|
96
110
|
|
97
111
|
|
data/lib/stevedore/rsruby.rb
CHANGED
@@ -3,34 +3,21 @@ class Stevedore
|
|
3
3
|
|
4
4
|
module RSRuby
|
5
5
|
|
6
|
-
def rsruby
|
6
|
+
def self.rsruby
|
7
7
|
@rsruby ||= ::RSRuby.instance
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
rsruby.
|
10
|
+
def rsruby
|
11
|
+
@rsruby ||= ::RSRuby.instance
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
rsruby.sd(self)
|
16
|
-
end
|
14
|
+
def mean; rsruby.mean(self); end
|
17
15
|
|
18
|
-
def
|
19
|
-
rsruby.median(self)
|
20
|
-
end
|
16
|
+
def standard_deviation; rsruby.sd(self); end
|
21
17
|
|
22
|
-
def self
|
23
|
-
@rsruby ||= ::RSRuby.instance
|
24
|
-
end
|
18
|
+
def median; rsruby.median(self); end
|
25
19
|
|
26
|
-
def self.power_test(args)
|
27
|
-
delta, power, sig_level, sd = args[:delta], args[:power], args[:sig_level], args[:sd]
|
28
|
-
if sd < 0.00007
|
29
|
-
warn "Stddev is very small, which makes power.t.test sad. \nSetting stddev to 0.00007 so we can get this done."
|
30
|
-
sd = 0.00007
|
31
|
-
end
|
32
|
-
rsruby.power_t_test( :delta => delta, :power => power, :sig_level => sig_level, :sd => sd)
|
33
|
-
end
|
20
|
+
def self.power_test(args); rsruby.power_t_test( args ); end
|
34
21
|
|
35
22
|
end
|
36
23
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
begin
|
2
|
+
require 'stevedore/rsruby'
|
3
|
+
Stats = Stevedore::RSRuby
|
4
|
+
rescue LoadError
|
5
|
+
require 'stevedore/stats'
|
6
|
+
end
|
7
|
+
|
8
|
+
class Stevedore
|
9
|
+
|
10
|
+
class Sample < Array
|
11
|
+
include Stats
|
12
|
+
|
13
|
+
attr_reader :flat
|
14
|
+
|
15
|
+
alias :old_to_a :to_a
|
16
|
+
alias :old_mean :mean
|
17
|
+
alias :old_sd :standard_deviation
|
18
|
+
alias :old_median :median
|
19
|
+
alias :old_min :min
|
20
|
+
alias :old_max :max
|
21
|
+
|
22
|
+
def to_a
|
23
|
+
self.map { |a| a.is_a?( Sample ) ? a.to_a : a }
|
24
|
+
end
|
25
|
+
|
26
|
+
def mean; (@flat ||= self.flatten).old_mean; end
|
27
|
+
|
28
|
+
def standard_deviation; (@flat ||= self.flatten).old_sd; end
|
29
|
+
|
30
|
+
def median; (@flat ||= self.flatten).old_median; end
|
31
|
+
|
32
|
+
def min; (@flat ||= self.flatten).old_min; end
|
33
|
+
|
34
|
+
def max; (@flat ||= self.flatten).old_max; end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/stevedore/shell_r.rb
CHANGED
data/lib/stevedore/stats.rb
CHANGED
@@ -1,30 +1,41 @@
|
|
1
1
|
class Stevedore
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
rescue
|
8
|
-
require 'mathstats'
|
9
|
-
Stats = Mathstats
|
10
|
-
module Stats
|
11
|
-
unless defined?(median)
|
12
|
-
def median
|
13
|
-
sorted = self.sort; i = sorted.size % 2
|
14
|
-
case i
|
15
|
-
when 0 then sorted[i/2 - 1, 2].mean
|
16
|
-
when 1 then sorted[i/2].to_f
|
17
|
-
end if sorted.size > 0
|
18
|
-
end
|
19
|
-
end
|
20
|
-
def self.power_test(*args)
|
21
|
-
Stevedore::ShellR.new.power_test(*args)
|
22
|
-
end
|
3
|
+
module Stats
|
4
|
+
|
5
|
+
def sum
|
6
|
+
s = 0; self.each { |element| s = s + element }; s
|
23
7
|
end
|
24
|
-
|
8
|
+
|
9
|
+
def mean
|
10
|
+
self.sum.to_f / self.size
|
11
|
+
end
|
12
|
+
|
13
|
+
def variance
|
14
|
+
n = self.size
|
15
|
+
denom = n - 1
|
16
|
+
m = self.mean
|
17
|
+
s = 0
|
18
|
+
self.each { |element| s = s + (element - m)**2; }
|
19
|
+
s / denom
|
20
|
+
end
|
21
|
+
|
22
|
+
def standard_deviation
|
23
|
+
Math.sqrt( self.variance )
|
24
|
+
end
|
25
|
+
|
26
|
+
def median
|
27
|
+
sorted = self.sort; i = sorted.size % 2
|
28
|
+
case i
|
29
|
+
when 0 then sorted[i/2 - 1, 2].mean
|
30
|
+
when 1 then sorted[i/2].to_f
|
31
|
+
end if sorted.size > 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.power_test(*args)
|
35
|
+
Stevedore::ShellR.new.power_test(*args)
|
36
|
+
end
|
37
|
+
|
25
38
|
end
|
26
|
-
|
27
|
-
Array.send :include, Stats
|
28
39
|
|
29
40
|
end
|
30
41
|
|
data/lib/stevedore.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'benchmark'
|
2
|
-
require '
|
2
|
+
require 'yaml'
|
3
|
+
require 'stevedore/sample'
|
3
4
|
require 'stevedore/shell_r'
|
4
5
|
require 'stevedore/class'
|
5
6
|
require 'stevedore/instance'
|
6
7
|
|
7
|
-
class Stevedore
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
Steve = Stevedore
|
8
|
+
class Stevedore; end
|
9
|
+
Steve = Stevedore
|
data/stevedore.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{stevedore}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Matthew King"]
|
9
|
-
s.date = %q{2009-
|
10
|
-
s.description = %q{Benchmarking with
|
11
|
-
s.email = %q{automatthew
|
12
|
-
s.extra_rdoc_files = ["lib/stevedore/class.rb", "lib/stevedore/instance.rb", "lib/stevedore/rsruby.rb", "lib/stevedore/shell_r.rb", "lib/stevedore/stats.rb", "lib/stevedore.rb", "README"]
|
13
|
-
s.files = ["examples/data.yml", "examples/instance_eval.rb", "examples/stats_libs.rb", "lib/stevedore/class.rb", "lib/stevedore/instance.rb", "lib/stevedore/rsruby.rb", "lib/stevedore/shell_r.rb", "lib/stevedore/stats.rb", "lib/stevedore.rb", "Manifest", "Rakefile", "README", "stevedore.gemspec", "test/helper.rb", "test/test_R.rb", "test/test_sample.rb"]
|
9
|
+
s.date = %q{2009-02-09}
|
10
|
+
s.description = %q{Benchmarking framework with some statistickal stuff}
|
11
|
+
s.email = %q{self@automatthew.com}
|
12
|
+
s.extra_rdoc_files = ["lib/stevedore/class.rb", "lib/stevedore/instance.rb", "lib/stevedore/rsruby.rb", "lib/stevedore/sample.rb", "lib/stevedore/shell_r.rb", "lib/stevedore/stats.rb", "lib/stevedore.rb", "README"]
|
13
|
+
s.files = ["examples/aliasing.rb", "examples/concat.rb", "examples/data.yml", "examples/instance_eval.rb", "examples/stats_libs.rb", "examples/stevedata/appending_strings.yaml", "examples/stevedata/interpolating_strings.yaml", "examples/variance.rb", "lib/stevedore/class.rb", "lib/stevedore/instance.rb", "lib/stevedore/rsruby.rb", "lib/stevedore/sample.rb", "lib/stevedore/shell_r.rb", "lib/stevedore/stats.rb", "lib/stevedore.rb", "Manifest", "Rakefile", "README", "stevedore.gemspec", "test/helper.rb", "test/test_R.rb", "test/test_sample.rb"]
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.homepage = %q{}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Stevedore", "--main", "README"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = %q{stevedore}
|
19
19
|
s.rubygems_version = %q{1.3.1}
|
20
|
-
s.summary = %q{Benchmarking with
|
20
|
+
s.summary = %q{Benchmarking framework with some statistickal stuff}
|
21
21
|
s.test_files = ["test/helper.rb", "test/test_R.rb", "test/test_sample.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
data/test/helper.rb
CHANGED
data/test/test_sample.rb
CHANGED
@@ -6,7 +6,7 @@ describe "Stevedore::Sample" do
|
|
6
6
|
|
7
7
|
before do
|
8
8
|
@sample = Sample.new((1..40).to_a)
|
9
|
-
@nested_sample = Sample.new [
|
9
|
+
@nested_sample = Sample.new [Sample.new((1..40).to_a), Sample.new((1..40).to_a), Sample.new((1..40).to_a) ]
|
10
10
|
end
|
11
11
|
|
12
12
|
it "a flattened Sample is still a Sample" do
|
@@ -24,4 +24,10 @@ describe "Stevedore::Sample" do
|
|
24
24
|
@nested_sample.standard_deviation.to_i.should == 11
|
25
25
|
end
|
26
26
|
|
27
|
+
it "can become simple arrays" do
|
28
|
+
@nested_sample.to_a.each do |a|
|
29
|
+
a.class.should == Array
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
27
33
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: automatthew-stevedore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew King
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-02-09 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -21,8 +21,8 @@ dependencies:
|
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: "0"
|
23
23
|
version:
|
24
|
-
description: Benchmarking with
|
25
|
-
email: automatthew
|
24
|
+
description: Benchmarking framework with some statistickal stuff
|
25
|
+
email: self@automatthew.com
|
26
26
|
executables: []
|
27
27
|
|
28
28
|
extensions: []
|
@@ -31,17 +31,24 @@ extra_rdoc_files:
|
|
31
31
|
- lib/stevedore/class.rb
|
32
32
|
- lib/stevedore/instance.rb
|
33
33
|
- lib/stevedore/rsruby.rb
|
34
|
+
- lib/stevedore/sample.rb
|
34
35
|
- lib/stevedore/shell_r.rb
|
35
36
|
- lib/stevedore/stats.rb
|
36
37
|
- lib/stevedore.rb
|
37
38
|
- README
|
38
39
|
files:
|
40
|
+
- examples/aliasing.rb
|
41
|
+
- examples/concat.rb
|
39
42
|
- examples/data.yml
|
40
43
|
- examples/instance_eval.rb
|
41
44
|
- examples/stats_libs.rb
|
45
|
+
- examples/stevedata/appending_strings.yaml
|
46
|
+
- examples/stevedata/interpolating_strings.yaml
|
47
|
+
- examples/variance.rb
|
42
48
|
- lib/stevedore/class.rb
|
43
49
|
- lib/stevedore/instance.rb
|
44
50
|
- lib/stevedore/rsruby.rb
|
51
|
+
- lib/stevedore/sample.rb
|
45
52
|
- lib/stevedore/shell_r.rb
|
46
53
|
- lib/stevedore/stats.rb
|
47
54
|
- lib/stevedore.rb
|
@@ -82,7 +89,7 @@ rubyforge_project: stevedore
|
|
82
89
|
rubygems_version: 1.2.0
|
83
90
|
signing_key:
|
84
91
|
specification_version: 2
|
85
|
-
summary: Benchmarking with
|
92
|
+
summary: Benchmarking framework with some statistickal stuff
|
86
93
|
test_files:
|
87
94
|
- test/helper.rb
|
88
95
|
- test/test_R.rb
|