automatthew-stevedore 0.1.0 → 0.2.0
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 +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
|