flori-bullshit 0.1.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.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bullshit'
4
+ require File.join(File.dirname(__FILE__), 'fibonacci')
5
+
6
+ FibonacciBenchmark.run # to demonstrate loading
7
+
8
+ Bullshit.compare do
9
+ benchmark FibonacciBenchmark, :fib_iter, :load => yes
10
+ benchmark FibonacciBenchmark, :fib_memo, :load => yes
11
+ end
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bullshit'
4
+
5
+ class FibonacciBenchmark < Bullshit::RepeatCase
6
+ warmup yes
7
+
8
+ iterations 500
9
+
10
+ truncate_data do
11
+ alpha_level 0.05
12
+ window_size 10
13
+ slope_angle 0.003
14
+ end
15
+
16
+ output_dir 'data'
17
+ data_file yes
18
+ histogram yes
19
+
20
+ autocorrelation do
21
+ alpha_level 0.05
22
+ max_lags 50
23
+ file yes
24
+ end
25
+
26
+ MIN_N = 10_000
27
+ RANGE_N = 100
28
+
29
+ def rand_n
30
+ MIN_N + rand(RANGE_N + 1)
31
+ end
32
+
33
+ def fib_iter(n)
34
+ a, b = 0, 1
35
+ while (n -= 1) >= 0
36
+ a, b = a + b, a
37
+ end
38
+ a
39
+ end
40
+
41
+ def fib_memo(n)
42
+ @fib_memo ||= Hash.new do |f, i|
43
+ f[i] = fib_iter(i)
44
+ end
45
+ @fib_memo[n]
46
+ end
47
+
48
+ def before_fib_iter
49
+ @n = rand_n
50
+ end
51
+
52
+ def benchmark_fib_iter
53
+ @result = fib_iter(@n)
54
+ end
55
+
56
+ def after_fib_iter
57
+ @result == fib_iter(@n) or raise "wrong result"
58
+ end
59
+
60
+ def before_fib_memo
61
+ @n = rand_n
62
+ end
63
+
64
+ def benchmark_fib_memo
65
+ @result = fib_memo(@n)
66
+ end
67
+
68
+ def after_fib_memo
69
+ @result == fib_iter(@n) or raise "wrong result"
70
+ end
71
+
72
+ def teardown_fib_memo
73
+ @fib_memo = nil
74
+ end
75
+ end
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bullshit'
4
+
5
+ module MyCases
6
+ def setup
7
+ @n = 1_000
8
+ @setup_general = true
9
+ end
10
+
11
+ def teardown
12
+ raise 'setup_general not set' unless @setup_general
13
+ end
14
+
15
+ def setup_for
16
+ @test_setup = true
17
+ end
18
+
19
+ def benchmark_for
20
+ a = []
21
+ for i in 1 .. @n
22
+ a << i ** 2
23
+ end
24
+ end
25
+
26
+ def teardown_for
27
+ raise "test_setup not set" unless @test_setup
28
+ end
29
+
30
+ def benchmark_times
31
+ a = []
32
+ i = 1
33
+ @n.times do
34
+ a << i ** 2
35
+ i += 1
36
+ end
37
+ end
38
+
39
+ def benchmark_loop
40
+ a = []
41
+ i = 1
42
+ loop do
43
+ i < @n or break
44
+ a << i ** 2
45
+ i += 1
46
+ end
47
+ end
48
+
49
+ def benchmark_while
50
+ a = []
51
+ i = 1
52
+ while i < @n
53
+ a << i ** 2
54
+ i += 1
55
+ end
56
+ end
57
+
58
+ def benchmark_while_fast
59
+ i = 1
60
+ while i < @n
61
+ a = i ** 2
62
+ i += 1
63
+ end
64
+ end
65
+
66
+ def benchmark_inject
67
+ (1..@n).inject([]) { |a, i| a << i ** 2 }
68
+ end
69
+
70
+ def benchmark_inject2
71
+ (1..@n).inject([]) { |a, i| a << i ** 2 }
72
+ end
73
+ end
74
+
75
+ class IterationTimeBenchmark < Bullshit::TimeCase
76
+ compare_time total
77
+ warmup yes
78
+ duration 1
79
+ batch_size 5
80
+
81
+ covering do
82
+ alpha_level 0.01
83
+ end
84
+
85
+ autocorrelation do
86
+ file yes
87
+ end
88
+
89
+ output_dir 'data'
90
+ data_file yes
91
+
92
+ histogram yes
93
+
94
+ include MyCases
95
+ end
96
+
97
+ class IterationRepeatBenchmark < Bullshit::RepeatCase
98
+ warmup yes
99
+ iterations 1000
100
+
101
+ covering do
102
+ alpha_level 0.01
103
+ end
104
+
105
+ autocorrelation yes
106
+
107
+ data_file yes
108
+ output_dir 'data'
109
+
110
+ histogram do
111
+ bins 20
112
+ file yes
113
+ end
114
+
115
+ include MyCases
116
+ end
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bullshit'
4
+
5
+ module Original
6
+ class Person
7
+ attr_reader :count, :prev, :next
8
+ attr_writer :count, :prev, :next
9
+
10
+ def initialize(count)
11
+ @count = count
12
+ @prev = nil
13
+ @next = nil
14
+ end
15
+
16
+ def shout(shout, deadif)
17
+ if shout < deadif
18
+ return shout + 1
19
+ end
20
+ @prev.next = @next
21
+ @next.prev = @prev
22
+ return 1
23
+ end
24
+ end
25
+
26
+ class Chain
27
+ attr_reader :first
28
+ attr_writer :first
29
+
30
+ def initialize(size)
31
+ @first = nil
32
+ last = nil
33
+ for i in (1..size)
34
+ current = Person.new(i)
35
+ if @first == nil
36
+ @first = current
37
+ end
38
+ if last != nil
39
+ last.next = current
40
+ current.prev = last
41
+ end
42
+ last = current
43
+ end
44
+ @first.prev = last
45
+ last.next = @first
46
+ end
47
+
48
+ def kill(nth)
49
+ current = @first
50
+ shout = 1
51
+ while current.next != current
52
+ shout = current.shout(shout,nth)
53
+ current = current.next
54
+ end
55
+ @first = current
56
+ return current
57
+ end
58
+ end
59
+ end
60
+
61
+ module Improved
62
+ class Person
63
+ attr_accessor :count, :prev, :next
64
+
65
+ def initialize(count)
66
+ @count = count
67
+ end
68
+
69
+ def shout(shout, deadif)
70
+ if shout < deadif
71
+ return shout + 1
72
+ end
73
+ @prev.next = @next
74
+ @next.prev = @prev
75
+ 1
76
+ end
77
+ end
78
+
79
+ class Chain
80
+ attr_accessor :first
81
+
82
+ def initialize(size)
83
+ last = nil
84
+ 1.upto(size) do |i|
85
+ current = Person.new(i)
86
+ @first ||= current
87
+ if last
88
+ last.next = current
89
+ current.prev = last
90
+ end
91
+ last = current
92
+ end
93
+ @first.prev = last
94
+ last.next = @first
95
+ end
96
+
97
+ def kill(nth)
98
+ current = @first
99
+ shout = 1
100
+ while current.next != current
101
+ shout = current.shout(shout,nth)
102
+ current = current.next
103
+ end
104
+ @first = current
105
+ end
106
+ end
107
+ end
108
+
109
+ class JosephusBenchmark < Bullshit::RepeatCase
110
+ compare_time real
111
+ warmup aggressive
112
+ iterations 500
113
+
114
+ autocorrelation yes
115
+
116
+ N = 1001 # 41
117
+
118
+ output_dir 'data'
119
+ data_file yes
120
+
121
+ output_filename "#{benchmark_name}.log"
122
+
123
+ histogram do
124
+ bins 20
125
+ end
126
+
127
+ def benchmark_josephus_original
128
+ chain = Original::Chain.new(N)
129
+ chain.kill(3)
130
+ end
131
+
132
+ def benchmark_josephus_improved
133
+ chain = Improved::Chain.new(N)
134
+ chain.kill(3)
135
+ end
136
+ end
@@ -0,0 +1,363 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bullshit'
4
+
5
+ class SortingBenchmark < Bullshit::RangeCase
6
+ compare_time real
7
+ warmup yes
8
+ range 1..200
9
+ scatter 3
10
+
11
+ data_file yes
12
+ output_dir 'data'
13
+
14
+ def prepare_random_array
15
+ @ary = Array.new(args) { rand(args * 10) }
16
+ end
17
+
18
+ def prepare_sorted_array
19
+ @ary = Array.new(args) { rand(args * 10) }
20
+ @ary.sort!
21
+ end
22
+
23
+ def check_result
24
+ @result == @ary.sort or raise "sorting failure"
25
+ end
26
+
27
+ # Ruby internal sort (an optimized quicksort implementation)
28
+
29
+ # random array
30
+ alias before_ruby_sort prepare_random_array
31
+
32
+ def benchmark_ruby_sort
33
+ @result = @ary.sort
34
+ end
35
+
36
+ alias after_ruby_sort check_result
37
+
38
+ # sorted array
39
+ alias before_ruby_sort_sorted prepare_sorted_array
40
+
41
+ alias benchmark_ruby_sort_sorted benchmark_ruby_sort
42
+
43
+ alias after_ruby_sort_sorted check_result
44
+
45
+ # Quicksort in Ruby
46
+
47
+ def quicksort(a)
48
+ return [] if a.empty?
49
+ left, right = a[1..-1].partition { |y| y <= a.first }
50
+ quicksort(left) + [ a.first ] + quicksort(right)
51
+ end
52
+
53
+ # random array
54
+ alias before_quicksort prepare_random_array
55
+
56
+ def benchmark_quicksort
57
+ @result = quicksort @ary
58
+ end
59
+
60
+ alias after_quicksort check_result
61
+
62
+ # sorted array
63
+ alias before_quicksort_sorted prepare_sorted_array
64
+
65
+ alias benchmark_quicksort_sorted benchmark_quicksort
66
+
67
+ alias after_quicksort_sorted check_result
68
+
69
+ # Quicksort in Ruby with median pivot
70
+
71
+ def find_median_index(orig_a)
72
+ a = orig_a.dup
73
+ k = a.size / 2
74
+ l = 0
75
+ m = a.size - 1
76
+ while l < m
77
+ x = a[k]
78
+ i = l
79
+ j = m
80
+ begin
81
+ i += 1 while a[i] < x
82
+ j -= 1 while x < a[j]
83
+ if i <= j
84
+ a[i], a[j] = a[j], a[i]
85
+ i += 1
86
+ j -= 1
87
+ end
88
+ end while i <= j
89
+ l = i if j < k
90
+ m = j if k < i
91
+ end
92
+ orig_a.index(a[k])
93
+ end
94
+
95
+ def median_quicksort(a)
96
+ return [] if a.empty?
97
+ i = find_median_index a
98
+ a[0], a[i] = a[i], a[0]
99
+ left, right = a[1..-1].partition { |y| y <= a.first }
100
+ median_quicksort(left) + [ a.first ] + median_quicksort(right)
101
+ end
102
+
103
+ # random array
104
+ alias before_median_quicksort prepare_random_array
105
+
106
+ def benchmark_median_quicksort
107
+ @result = median_quicksort @ary
108
+ end
109
+
110
+ alias after_median_quicksort check_result
111
+
112
+ # sorted array
113
+ alias before_median_quicksort_sorted prepare_sorted_array
114
+
115
+ alias benchmark_median_quicksort_sorted benchmark_median_quicksort
116
+
117
+ alias after_median_quicksort_sorted check_result
118
+
119
+ # Insertionsort-Quicksort-Hybrid in Ruby
120
+
121
+ def quicksort_hybrid(a)
122
+ if a.size < 7
123
+ insertionsort(a)
124
+ else
125
+ i = find_median_index a
126
+ a[0], a[i] = a[i], a[0]
127
+ left, right = a[1..-1].partition { |y| y <= a.first }
128
+ quicksort_hybrid(left) + [ a.first ] + quicksort_hybrid(right)
129
+ end
130
+ end
131
+
132
+ # random array
133
+ alias before_quicksort_hybrid prepare_random_array
134
+
135
+ def benchmark_quicksort_hybrid
136
+ @result = quicksort_hybrid @ary
137
+ end
138
+
139
+ alias after_quicksort_hybrid check_result
140
+
141
+ # sorted array
142
+ alias before_quicksort_hybrid_sorted prepare_sorted_array
143
+
144
+ alias benchmark_quicksort_hybrid_sorted benchmark_quicksort_hybrid
145
+
146
+ alias after_quicksort_hybrid_sorted check_result
147
+
148
+ # Selectionsort in Ruby
149
+
150
+ def selectionsort(a)
151
+ a = a.dup
152
+ for start in 0...(a.size - 1)
153
+ min = start
154
+ for i in (start + 1)...a.size
155
+ a[i] < a[min] and min = i
156
+ end
157
+ a[start], a[min] = a[min], a[start]
158
+ end
159
+ a
160
+ end
161
+
162
+ # random array
163
+ alias before_selectionsort prepare_random_array
164
+
165
+ def benchmark_selectionsort
166
+ @result = selectionsort @ary
167
+ end
168
+
169
+ alias after_selectionsort check_result
170
+
171
+ # sorted array
172
+ alias before_selectionsort_sorted prepare_sorted_array
173
+
174
+ alias benchmark_selectionsort_sorted benchmark_selectionsort
175
+
176
+ alias after_selectionsort_sorted check_result
177
+
178
+ # Insertionsort in Ruby
179
+
180
+ def insertionsort(a)
181
+ a = a.dup
182
+ for i in 1...a.size
183
+ j, x = i - 1, a[i]
184
+ while j >= 0 and a[j] > x
185
+ a[j + 1] = a[j]
186
+ j -= 1
187
+ end
188
+ a[j + 1] = x
189
+ end
190
+ a
191
+ end
192
+
193
+ # random array
194
+ alias before_insertionsort prepare_random_array
195
+
196
+ def benchmark_insertionsort
197
+ @result = insertionsort @ary
198
+ end
199
+
200
+ alias after_insertionsort check_result
201
+
202
+ # sorted array
203
+ alias before_insertionsort_sorted prepare_sorted_array
204
+
205
+ alias benchmark_insertionsort_sorted benchmark_insertionsort
206
+
207
+ alias after_insertionsort_sorted check_result
208
+
209
+ # Shellsort in Ruby
210
+
211
+ def shellsort(a)
212
+ a = a.dup
213
+ s = a.size / 2
214
+ while s > 0
215
+ for i in 0...a.size
216
+ j, t = i, a[i]
217
+ while j >= s and a[j - s] > t
218
+ a[j] = a[j - s]
219
+ j -= s
220
+ end
221
+ a[j] = t
222
+ end
223
+ s = s == 1 ? 0 : s / 2
224
+ end
225
+ a
226
+ end
227
+
228
+ # random array
229
+ alias before_shellsort prepare_random_array
230
+
231
+ def benchmark_shellsort
232
+ @result = shellsort @ary
233
+ end
234
+
235
+ alias after_shellsort check_result
236
+
237
+ # sorted array
238
+ alias before_shellsort_sorted prepare_sorted_array
239
+
240
+ alias benchmark_shellsort_sorted benchmark_shellsort
241
+
242
+ alias after_shellsort_sorted check_result
243
+
244
+ # Bubblesort in Ruby
245
+
246
+ def bubblesort(a)
247
+ a = a.dup
248
+ for j in 0...a.size
249
+ for i in 1...(a.size - j)
250
+ a[i], a[i - 1] = a[i - 1], a[i] if a[i] < a[i - 1]
251
+ end
252
+ end
253
+ a
254
+ end
255
+
256
+ # random array
257
+ alias before_bubblesort prepare_random_array
258
+
259
+ def benchmark_bubblesort
260
+ @result = bubblesort @ary
261
+ end
262
+
263
+ alias after_bubblesort check_result
264
+
265
+ # sorted array
266
+ alias before_bubblesort_sorted prepare_sorted_array
267
+
268
+ alias benchmark_bubblesort_sorted benchmark_bubblesort
269
+
270
+ alias after_bubblesort_sorted check_result
271
+
272
+ # Mergesort in Ruby
273
+
274
+ def merge(a, b)
275
+ case
276
+ when a.empty? then b
277
+ when b.empty? then a
278
+ when a.first < b.first then a[0, 1].concat merge(a[1..-1], b)
279
+ else b[0, 1].concat merge(a, b[1..-1])
280
+ end
281
+ end
282
+
283
+ def mergesort(a)
284
+ if a.size <= 1
285
+ a
286
+ else
287
+ mid = a.size / 2
288
+ merge( mergesort(a[0, mid]), mergesort(a[mid..-1]) )
289
+ end
290
+ end
291
+
292
+ # random array
293
+ alias before_mergesort prepare_random_array
294
+
295
+ def benchmark_mergesort
296
+ @result = mergesort @ary
297
+ end
298
+
299
+ alias after_mergesort check_result
300
+
301
+ # sorted array
302
+ alias before_mergesort_sorted prepare_sorted_array
303
+
304
+ alias benchmark_mergesort_sorted benchmark_mergesort
305
+
306
+ alias after_mergesort_sorted check_result
307
+
308
+ # Heapsort in Ruby
309
+ def sift_down(a, start, ende)
310
+ root = start
311
+ while root * 2 + 1 <= ende
312
+ child = root * 2 + 1
313
+ if child + 1 <= ende and a[child] < a[child + 1]
314
+ child += 1
315
+ end
316
+ if a[root] < a[child]
317
+ a[root], a[child] = a[child], a[root]
318
+ root = child
319
+ else
320
+ return
321
+ end
322
+ end
323
+ end
324
+
325
+ def heapify(a)
326
+ count = a.size
327
+
328
+ start = (count - 2) / 2
329
+ while start >= 0
330
+ sift_down(a, start, count - 1)
331
+ start -= 1
332
+ end
333
+ end
334
+
335
+ def heapsort(a)
336
+ a = a.dup
337
+ heapify(a)
338
+
339
+ ende = a.size - 1
340
+ while ende > 0
341
+ a[ende], a[0] = a[0], a[ende]
342
+ ende -= 1
343
+ sift_down(a, 0, ende)
344
+ end
345
+ a
346
+ end
347
+
348
+ # random array
349
+ alias before_heapsort prepare_random_array
350
+
351
+ def benchmark_heapsort
352
+ @result = heapsort @ary
353
+ end
354
+
355
+ alias after_heapsort check_result
356
+
357
+ # sorted array
358
+ alias before_heapsort_sorted prepare_sorted_array
359
+
360
+ alias benchmark_heapsort_sorted benchmark_heapsort
361
+
362
+ alias after_heapsort_sorted check_result
363
+ end