benchmark-bigo 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,15 +9,6 @@ module Benchmark
9
9
  def initialize
10
10
  @per_iterations = 0
11
11
  @entries = {}
12
- @logscale = false
13
- end
14
-
15
- def logscale?
16
- @logscale
17
- end
18
-
19
- def logscale!
20
- @logscale = true
21
12
  end
22
13
 
23
14
  def add_entry label, microseconds, iters, ips, ips_sd, measurement_cycle
@@ -28,103 +19,28 @@ module Benchmark
28
19
  @entries[group_label].last
29
20
  end
30
21
 
31
- def scaled_iterations
32
- (@per_iterations.to_f * 50 )
33
- end
34
-
35
- def chart_hash group_label
22
+ # retrieve benchmark data for a particular label
23
+ def data_for group_label
36
24
  @entries[group_label].collect do |report|
37
25
  size = report.label.split(' ').last.to_i
38
- seconds_per_scaled_iters = scaled_iterations / report.ips.to_f
26
+ microseconds_per_iters = 1000000.0 / report.ips.to_f
39
27
 
40
28
  {label: size,
41
- seconds_per_scaled_iters: seconds_per_scaled_iters,
29
+ microseconds_per_iters: microseconds_per_iters,
42
30
  ips: report.ips
43
31
  }
44
32
  end
45
33
  end
46
34
 
47
- def chart_for group_label
48
- chart_hash = chart_hash group_label
49
- Hash[chart_hash.collect{|h| [h[:label], h[:seconds_per_scaled_iters]]}]
50
- end
51
-
52
- def chart_data
35
+ # retrieve a summary of data for the benchmark report
36
+ def data
53
37
  @entries.keys.map do |k|
54
- data = chart_for k
55
- {name: k, data: data }
56
- end
57
- end
58
-
59
- def chart_opts chart_data
60
-
61
- axis_type = logscale? ? 'logarithmic' : 'linear'
62
-
63
- if chart_data.is_a? Array
64
- min = chart_data.collect{|d| d[:data].values.min}.min
65
- max = chart_data.collect{|d| d[:data].values.max}.max
66
-
67
- elsif chart_data.is_a? Hash
68
- min = chart_data[:data].values.min
69
- max = chart_data[:data].values.max
38
+ key_data = data_for(k)
39
+ data = Hash[key_data.collect{|h| [h[:label], h[:microseconds_per_iters]]}]
40
+ {name: k, data: data}
70
41
  end
71
-
72
- orange = "#f0662d"
73
- purple = "#8062a6"
74
- light_green = "#7bc545"
75
- med_blue = "#0883b2"
76
- yellow = "#ffaa00"
77
-
78
- {
79
- discrete: true,
80
- width: "800px",
81
- height: "500px",
82
- min: (min * 0.8).floor,
83
- max: (max * 1.2).ceil,
84
- library: {
85
- colors: [orange, purple, light_green, med_blue, yellow],
86
- xAxis: {type: axis_type, title: {text: "Size"}},
87
- yAxis: {type: axis_type, title: {text: "Seconds per #{scaled_iterations.to_i} Iterations"}}
88
- }
89
- }
90
42
  end
91
43
 
92
- def comparison_chart_data chart_data, sizes
93
- sample_size = sizes.first
94
-
95
- # can't take log of 1,
96
- # so it can't be used as the sample
97
- if sample_size == 1
98
- sample_size = sizes[1]
99
- end
100
-
101
- sample = chart_data[:data][sample_size]
102
-
103
- logn_sample = sample/Math.log10(sample_size)
104
- n_sample = sample/sample_size
105
- nlogn_sample = sample/(sample_size * Math.log10(sample_size))
106
- n2_sample = sample/(sample_size * sample_size)
107
-
108
- logn_data = {}
109
- n_data = {}
110
- nlogn_data = {}
111
- n2_data = {}
112
-
113
- sizes.each do |n|
114
- logn_data[n] = Math.log10(n) * logn_sample
115
- n_data[n] = n * n_sample
116
- nlogn_data[n] = n * Math.log10(n) * nlogn_sample
117
- n2_data[n] = n * n * n2_sample
118
- end
119
-
120
- comparison_data = []
121
- comparison_data << chart_data
122
- comparison_data << {name: 'log n', data: logn_data}
123
- comparison_data << {name: 'n', data: n_data}
124
- comparison_data << {name: 'n log n', data: nlogn_data}
125
- comparison_data << {name: 'n_sq', data: n2_data}
126
- comparison_data
127
- end
128
44
  end
129
45
  end
130
46
  end
@@ -12,6 +12,7 @@
12
12
 
13
13
  <%= line_chart chart[:data], chart[:opts] %>
14
14
  <% end %>
15
+ <h5>Ruby Version: <%= RUBY_VERSION %></h5>
15
16
  </body>
16
17
  </html>
17
18
 
@@ -0,0 +1,70 @@
1
+ require 'tempfile'
2
+
3
+ class Benchmark::BigO::TermPlot
4
+
5
+ def initialize report_data, sizes
6
+ @data = report_data
7
+ @sizes = sizes
8
+ @dat_file = Tempfile.new 'termplot'
9
+ end
10
+
11
+ def generate
12
+
13
+ write_dat_file
14
+
15
+ begin
16
+ IO.popen("gnuplot", "w") { |io| io.puts commands }
17
+ rescue
18
+ puts "You need to have gnuplot installed!"
19
+ puts "brew install gnuplot"
20
+ end
21
+ end
22
+
23
+ def write_dat_file
24
+ File.open(@dat_file.path, 'w') do |file|
25
+ dat_lines.each do |line|
26
+ file.puts line
27
+ end
28
+ end
29
+ end
30
+
31
+ def dat_lines
32
+ lines = []
33
+ @sizes.each do |size|
34
+ line = [size] + @data.collect{|d| d[:data][size] }
35
+ lines << line.join(' ')
36
+ end
37
+ lines
38
+ end
39
+
40
+ def title_for index
41
+ @data[index][:name]
42
+ end
43
+
44
+ def commands
45
+
46
+ cmds = []
47
+ cmds << "set term dumb"
48
+ cmds << "set key top left vertical inside width 3"
49
+
50
+ data_idx = 0
51
+
52
+ while data_idx < @data.length
53
+
54
+ if data_idx == 0
55
+ str = "plot '#{@dat_file.path}'"
56
+ else
57
+ str = "\"\""
58
+ end
59
+
60
+ str += " using 1:#{data_idx+2} title '#{title_for(data_idx)}' with lines"
61
+ str += ",\\" unless data_idx == @data.length-1
62
+
63
+ cmds << str
64
+
65
+ data_idx += 1
66
+ end
67
+
68
+ cmds
69
+ end
70
+ end
@@ -1,8 +1,8 @@
1
1
  module Benchmark
2
2
  module BigO
3
3
  class Version
4
- MAJOR = 0
5
- MINOR = 1
4
+ MAJOR = 1
5
+ MINOR = 0
6
6
  PATCH = 0
7
7
 
8
8
  def self.to_s
@@ -1,5 +1,6 @@
1
1
  require "minitest/autorun"
2
2
  require "benchmark/bigo"
3
+ require "tempfile"
3
4
 
4
5
  class TestBenchmarkBigo < MiniTest::Test
5
6
  def setup
@@ -11,146 +12,237 @@ class TestBenchmarkBigo < MiniTest::Test
11
12
  $stdout = @old_stdout
12
13
  end
13
14
 
14
- def test_bigo
15
- #skip('pass')
15
+ def test_bigo_defaults
16
+ report = Benchmark.bigo do |x|
17
+ x.config(:time => 1, :warmup => 1)
18
+ x.generate :array
19
+
20
+ # size 100 will sleep for .1 seconds, size 200 will sleep for .2 seconds
21
+ x.report("sleep") { |_, size| sleep(size / 1000.0) }
22
+ end
23
+
24
+ assert_equal 1, report.entries.keys.length
25
+ rep = report.entries["sleep"]
26
+
27
+ assert_equal 10, rep.size
28
+
29
+ 10.times do |i|
30
+ size = 100 + i*100
31
+ assert_equal "sleep #{size}", rep[i].label
32
+
33
+ iterations = 1000.0 / size
34
+ assert_equal iterations.ceil, rep[i].iterations
35
+ assert_in_delta iterations, rep[i].ips, 0.4
36
+ end
37
+ end
38
+
39
+ def test_bigo_config_options
16
40
 
17
41
  report = Benchmark.bigo do |x|
18
- x.config(:time => 1, :warmup => 1, :increments => 2)
42
+ x.config(:time => 1, :warmup => 1,
43
+ :steps => 3, :step_size => 200, :min_size => 50)
19
44
  x.generate :array
20
45
 
21
46
  x.report("#at") {|array, size| array.at rand(size) }
22
- x.report("#index") {|array, size| array.index rand(size) }
23
- x.report("sleep") { |a,b| sleep(0.25) }
47
+
48
+ # size 100 will sleep for .1 seconds, size 200 will sleep for .2 seconds
49
+ x.report("sleep") { |_, size| sleep(size / 1000.0) }
24
50
  end
25
51
 
26
- assert_equal 3, report.entries.length
52
+ assert_equal 2, report.entries.length
27
53
 
28
54
  assert report.entries.keys.include?("#at")
29
- assert report.entries.keys.include?("#index")
30
55
  assert report.entries.keys.include?("sleep")
31
56
 
32
57
  at_rep = report.entries["#at"]
33
- index_rep = report.entries["#index"]
34
58
  sleep_rep = report.entries["sleep"]
35
59
 
36
- assert_equal 2, at_rep.size
37
- assert_equal 2, index_rep.size
38
- assert_equal 2, sleep_rep.size
60
+ assert_equal 3, at_rep.size
61
+ assert_equal 3, sleep_rep.size
39
62
 
40
- assert_equal "#at 100", at_rep[0].label
41
- assert_equal "#at 200", at_rep[1].label
63
+ assert_equal "#at 50", at_rep[0].label
64
+ assert_equal "#at 250", at_rep[1].label
65
+ assert_equal "#at 450", at_rep[2].label
42
66
 
43
- assert_equal "#index 100", index_rep[0].label
44
- assert_equal "#index 200", index_rep[1].label
67
+ assert_equal "sleep 50", sleep_rep[0].label
68
+ assert_equal "sleep 250", sleep_rep[1].label
69
+ assert_equal "sleep 450", sleep_rep[2].label
45
70
 
46
- assert_equal "sleep 100", sleep_rep[0].label
47
- assert_equal "sleep 200", sleep_rep[1].label
71
+ assert_equal 20, sleep_rep[0].iterations
72
+ assert_in_delta 20.0, sleep_rep[0].ips, 0.6
48
73
 
49
- assert_equal 4, sleep_rep[0].iterations
50
- assert_in_delta 4.0, sleep_rep[0].ips, 0.2
74
+ assert_equal 4, sleep_rep[1].iterations
75
+ assert_in_delta 4.0, sleep_rep[1].ips, 0.2
51
76
 
52
77
  end
53
78
 
54
- def test_bigo_alternate_config
55
- #skip('pass')
79
+ def test_bigo_setters
56
80
  report = Benchmark.bigo do |x|
57
81
  x.time = 1
58
82
  x.warmup = 1
59
- x.increments = 2
60
- x.generate(:array)
61
- x.report("sleep") { |a,b| sleep(0.25) }
83
+ x.steps = 3
84
+ x.step_size = 200
85
+ x.min_size = 50
86
+ x.generate :array
87
+
88
+ x.report("#at") {|array, size| array.at rand(size) }
89
+
90
+ # size 100 will sleep for .1 seconds, size 200 will sleep for .2 seconds
91
+ x.report("sleep") { |_, size| sleep(size / 1000.0) }
62
92
  end
63
93
 
64
- rep = report.entries["sleep"]
65
- assert_equal 2, rep.size
94
+ assert_equal 2, report.entries.length
66
95
 
67
- assert_equal "sleep 100", rep[0].label
68
- assert_equal 4, rep[0].iterations
69
- assert_in_delta 4.0, rep[0].ips, 0.2
70
- end
96
+ assert report.entries.keys.include?("#at")
97
+ assert report.entries.keys.include?("sleep")
71
98
 
72
- def test_bigo_defaults
73
- #skip('pass')
74
- report = Benchmark.bigo do |x|
75
- x.config(:time => 1, :warmup => 1)
76
- x.generate :array
77
- x.report("sleep") { |a,b| sleep(0.25) }
78
- end
99
+ at_rep = report.entries["#at"]
100
+ sleep_rep = report.entries["sleep"]
79
101
 
80
- assert_equal 1, report.entries.keys.length
81
- rep = report.entries["sleep"]
102
+ assert_equal 3, at_rep.size
103
+ assert_equal 3, sleep_rep.size
82
104
 
83
- assert_equal 5, rep.size
105
+ assert_equal "#at 50", at_rep[0].label
106
+ assert_equal "#at 250", at_rep[1].label
107
+ assert_equal "#at 450", at_rep[2].label
84
108
 
85
- assert_equal "sleep 100", rep[0].label
86
- assert_equal "sleep 200", rep[1].label
87
- assert_equal "sleep 300", rep[2].label
88
- assert_equal "sleep 400", rep[3].label
89
- assert_equal "sleep 500", rep[4].label
109
+ assert_equal "sleep 50", sleep_rep[0].label
110
+ assert_equal "sleep 250", sleep_rep[1].label
111
+ assert_equal "sleep 450", sleep_rep[2].label
90
112
 
91
- assert_equal 4, rep[0].iterations
92
- assert_in_delta 4.0, rep[0].ips, 0.2
113
+ assert_equal 20, sleep_rep[0].iterations
114
+ assert_in_delta 20.0, sleep_rep[0].ips, 0.6
115
+
116
+ assert_equal 4, sleep_rep[1].iterations
117
+ assert_in_delta 4.0, sleep_rep[1].ips, 0.2
93
118
  end
94
119
 
95
- def test_bigo_exponential
96
- #skip('pass')
120
+ def test_bigo_generate_json
121
+ json_file = Tempfile.new 'data.json'
97
122
  report = Benchmark.bigo do |x|
98
- x.config(:time => 1, :warmup => 1, :increments => 2)
123
+ x.config(:time => 1, :warmup => 1, :steps => 2)
99
124
  x.generate :array
100
- x.exponential
101
- x.report("sleep") { |a,b| sleep(0.25) }
125
+
126
+ x.report("#at") {|array, size| array.at rand(size) }
127
+ x.json! json_file.path
102
128
  end
103
129
 
104
- rep = report.entries["sleep"]
130
+ json_data = json_file.read
131
+ assert json_data
132
+ data = JSON.parse json_data
133
+ assert data
134
+ assert_equal 1, data.size
135
+ assert_equal "#at", data[0]["name"]
136
+ assert data[0]["data"]
137
+ assert data[0]["data"]["100"]
138
+ assert data[0]["data"]["200"]
139
+ end
105
140
 
106
- assert_equal "sleep 1", rep[0].label
107
- assert_equal "sleep 10", rep[1].label
108
- assert_equal 4, rep[0].iterations
109
- assert_in_delta 4.0, rep[0].ips, 0.2
141
+ def test_bigo_generate_csv
142
+ csv_file = Tempfile.new 'data.csv'
143
+ report = Benchmark.bigo do |x|
144
+ x.config(:time => 1, :warmup => 1, :steps => 2)
145
+ x.generate :array
146
+
147
+ x.report("#at") {|array, size| array.at rand(size) }
148
+ x.csv! csv_file.path
149
+ end
150
+ data = CSV.read(csv_file.path)
151
+ assert data
152
+ assert_equal 2, data.size
153
+ assert_equal ['','100', '200'], data[0]
154
+ assert_equal "#at", data[1][0]
155
+ assert_equal data[1][0].size, 3
110
156
  end
111
157
 
112
- def test_bigo_increments_config
113
- #skip('pass')
158
+ def test_bigo_generate_chart
159
+ chart_file = Tempfile.new 'data.html'
114
160
  report = Benchmark.bigo do |x|
115
- x.config(:time => 1, :warmup => 1, :increments => 3)
161
+ x.config(:time => 1, :warmup => 1, :steps => 2)
116
162
  x.generate :array
117
163
 
118
164
  x.report("#at") {|array, size| array.at rand(size) }
165
+ x.chart! chart_file.path
166
+ x.compare!
119
167
  end
120
168
 
121
- assert_equal 1, report.entries.length
169
+ data = File.read(chart_file.path)
170
+ assert data
171
+ assert data.match('<h1>Growth Chart</h1>')
172
+ assert data.match('<h1>#at</h1>')
173
+ end
174
+
175
+ def test_generate_array
122
176
 
123
- assert report.entries.keys.include?("#at")
177
+ job = Benchmark::BigO::Job.new({:suite => nil,
178
+ :quiet => true})
124
179
 
125
- at_rep = report.entries["#at"]
180
+ job.generate :array
126
181
 
127
- assert_equal 3, at_rep.size
182
+ job.report('test') {|array, size| array.at rand(size) }
183
+
184
+ # should create 10 job entries
185
+ assert_equal 10, job.list.size
128
186
 
129
- assert_equal "#at 100", at_rep[0].label
130
- assert_equal "#at 200", at_rep[1].label
131
- assert_equal "#at 300", at_rep[2].label
187
+ # the generated object should be an Array
188
+ assert Array === job.list.first.generated
189
+
190
+ # the Array should have 100 elements
191
+ assert_equal 100, job.list.first.generated.size
192
+
193
+ # when sorted, the array should equal 0...100
194
+ assert_equal (0...100).to_a, job.list.first.generated.sort
132
195
  end
133
196
 
134
- def test_bigo_increments_setter
135
- #skip('pass')
136
- report = Benchmark.bigo do |x|
137
- x.config(:time => 1, :warmup => 1)
138
- x.increments = 3
139
- x.generate :array
197
+ def test_generate_string
140
198
 
141
- x.report("#at") {|array, size| array.at rand(size) }
142
- end
199
+ job = Benchmark::BigO::Job.new({:suite => nil,
200
+ :quiet => true})
143
201
 
144
- assert_equal 1, report.entries.length
202
+ job.generate :string
145
203
 
146
- assert report.entries.keys.include?("#at")
204
+ job.report('test') {|string, size| string[rand(size)] }
147
205
 
148
- at_rep = report.entries["#at"]
206
+ # should create 10 job entries
207
+ assert_equal 10, job.list.size
149
208
 
150
- assert_equal 3, at_rep.size
209
+ # the generated object should be a String
210
+ assert String === job.list.first.generated
211
+
212
+ # the String should have length 100
213
+ assert_equal 200, job.list.first.generated.length
214
+ end
215
+
216
+ def test_generate_size
217
+ job = Benchmark::BigO::Job.new({:suite => nil,
218
+ :quiet => true})
219
+
220
+ job.generate :size
221
+
222
+ job.report('test') {|size, _| size.to_i }
223
+
224
+ # should create 10 job entries
225
+ assert_equal 10, job.list.size
226
+
227
+ # the generated object should be an Integer
228
+ assert Integer === job.list.first.generated
229
+
230
+ # the Integer should be the size
231
+ assert_equal 100, job.list.first.generated
232
+ assert_equal 1000, job.list[-1].generated
233
+
234
+ end
235
+
236
+ def test_step
237
+ job = Benchmark::BigO::Job.new({:suite => nil,
238
+ :quiet => true})
239
+
240
+ job.min_size = 22
241
+ job.steps = 6
242
+ job.step_size = 10
151
243
 
152
- assert_equal "#at 100", at_rep[0].label
153
- assert_equal "#at 200", at_rep[1].label
154
- assert_equal "#at 300", at_rep[2].label
244
+ assert_equal 22, job.step(0)
245
+ assert_equal 32, job.step(1)
246
+ assert_equal 42, job.step(2)
155
247
  end
156
248
  end