fear 0.9.0 → 1.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.
Files changed (155) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rubocop.yml +39 -0
  3. data/.github/workflows/spec.yml +42 -0
  4. data/.gitignore +0 -1
  5. data/.rubocop.yml +4 -12
  6. data/.simplecov +17 -0
  7. data/CHANGELOG.md +40 -0
  8. data/Gemfile +5 -2
  9. data/Gemfile.lock +130 -0
  10. data/LICENSE.txt +1 -1
  11. data/README.md +1293 -97
  12. data/Rakefile +369 -1
  13. data/benchmarks/README.md +1 -0
  14. data/benchmarks/dry_do_vs_fear_for.txt +11 -0
  15. data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +11 -0
  16. data/benchmarks/factorial.txt +16 -0
  17. data/benchmarks/fear_gaurd_and1_vs_new.txt +13 -0
  18. data/benchmarks/fear_gaurd_and2_vs_and.txt +13 -0
  19. data/benchmarks/fear_gaurd_and3_vs_and_and.txt +13 -0
  20. data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +11 -0
  21. data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +13 -0
  22. data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +14 -0
  23. data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +11 -0
  24. data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +11 -0
  25. data/examples/pattern_extracting.rb +17 -0
  26. data/examples/pattern_extracting_ruby2.7.rb +15 -0
  27. data/examples/pattern_matching_binary_tree_set.rb +101 -0
  28. data/examples/pattern_matching_number_in_words.rb +60 -0
  29. data/fear.gemspec +34 -23
  30. data/lib/dry/types/fear.rb +8 -0
  31. data/lib/dry/types/fear/option.rb +125 -0
  32. data/lib/fear.rb +65 -15
  33. data/lib/fear/await.rb +33 -0
  34. data/lib/fear/awaitable.rb +28 -0
  35. data/lib/fear/either.rb +131 -71
  36. data/lib/fear/either_api.rb +23 -0
  37. data/lib/fear/either_pattern_match.rb +53 -0
  38. data/lib/fear/empty_partial_function.rb +38 -0
  39. data/lib/fear/extractor.rb +112 -0
  40. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +10 -0
  41. data/lib/fear/extractor/any_matcher.rb +17 -0
  42. data/lib/fear/extractor/array_head_matcher.rb +36 -0
  43. data/lib/fear/extractor/array_matcher.rb +40 -0
  44. data/lib/fear/extractor/array_splat_matcher.rb +16 -0
  45. data/lib/fear/extractor/empty_list_matcher.rb +20 -0
  46. data/lib/fear/extractor/extractor_matcher.rb +44 -0
  47. data/lib/fear/extractor/grammar.rb +203 -0
  48. data/lib/fear/extractor/grammar.treetop +129 -0
  49. data/lib/fear/extractor/identifier_matcher.rb +18 -0
  50. data/lib/fear/extractor/matcher.rb +53 -0
  51. data/lib/fear/extractor/matcher/and.rb +38 -0
  52. data/lib/fear/extractor/named_array_splat_matcher.rb +17 -0
  53. data/lib/fear/extractor/pattern.rb +58 -0
  54. data/lib/fear/extractor/typed_identifier_matcher.rb +26 -0
  55. data/lib/fear/extractor/value_matcher.rb +19 -0
  56. data/lib/fear/extractor_api.rb +35 -0
  57. data/lib/fear/failure.rb +46 -14
  58. data/lib/fear/failure_pattern_match.rb +10 -0
  59. data/lib/fear/for.rb +37 -95
  60. data/lib/fear/for_api.rb +68 -0
  61. data/lib/fear/future.rb +497 -0
  62. data/lib/fear/future_api.rb +21 -0
  63. data/lib/fear/left.rb +19 -2
  64. data/lib/fear/left_pattern_match.rb +11 -0
  65. data/lib/fear/none.rb +67 -3
  66. data/lib/fear/none_pattern_match.rb +14 -0
  67. data/lib/fear/option.rb +120 -56
  68. data/lib/fear/option_api.rb +40 -0
  69. data/lib/fear/option_pattern_match.rb +48 -0
  70. data/lib/fear/partial_function.rb +176 -0
  71. data/lib/fear/partial_function/and_then.rb +50 -0
  72. data/lib/fear/partial_function/any.rb +28 -0
  73. data/lib/fear/partial_function/combined.rb +53 -0
  74. data/lib/fear/partial_function/empty.rb +10 -0
  75. data/lib/fear/partial_function/guard.rb +80 -0
  76. data/lib/fear/partial_function/guard/and.rb +38 -0
  77. data/lib/fear/partial_function/guard/and3.rb +41 -0
  78. data/lib/fear/partial_function/guard/or.rb +38 -0
  79. data/lib/fear/partial_function/lifted.rb +23 -0
  80. data/lib/fear/partial_function/or_else.rb +64 -0
  81. data/lib/fear/partial_function_class.rb +38 -0
  82. data/lib/fear/pattern_match.rb +114 -0
  83. data/lib/fear/pattern_matching_api.rb +137 -0
  84. data/lib/fear/promise.rb +95 -0
  85. data/lib/fear/right.rb +20 -2
  86. data/lib/fear/right_biased.rb +6 -14
  87. data/lib/fear/right_pattern_match.rb +11 -0
  88. data/lib/fear/some.rb +55 -3
  89. data/lib/fear/some_pattern_match.rb +13 -0
  90. data/lib/fear/struct.rb +248 -0
  91. data/lib/fear/success.rb +35 -5
  92. data/lib/fear/success_pattern_match.rb +12 -0
  93. data/lib/fear/try.rb +136 -79
  94. data/lib/fear/try_api.rb +33 -0
  95. data/lib/fear/try_pattern_match.rb +33 -0
  96. data/lib/fear/unit.rb +32 -0
  97. data/lib/fear/utils.rb +39 -14
  98. data/lib/fear/version.rb +4 -1
  99. data/spec/dry/types/fear/option/constrained_spec.rb +22 -0
  100. data/spec/dry/types/fear/option/core_spec.rb +77 -0
  101. data/spec/dry/types/fear/option/default_spec.rb +21 -0
  102. data/spec/dry/types/fear/option/hash_spec.rb +58 -0
  103. data/spec/dry/types/fear/option/option_spec.rb +97 -0
  104. data/spec/fear/awaitable_spec.rb +17 -0
  105. data/spec/fear/done_spec.rb +8 -6
  106. data/spec/fear/either/mixin_spec.rb +17 -0
  107. data/spec/fear/either_pattern_match_spec.rb +37 -0
  108. data/spec/fear/either_pattern_matching_spec.rb +28 -0
  109. data/spec/fear/extractor/array_matcher_spec.rb +230 -0
  110. data/spec/fear/extractor/extractor_matcher_spec.rb +153 -0
  111. data/spec/fear/extractor/grammar_array_spec.rb +25 -0
  112. data/spec/fear/extractor/identified_matcher_spec.rb +49 -0
  113. data/spec/fear/extractor/identifier_matcher_spec.rb +68 -0
  114. data/spec/fear/extractor/pattern_spec.rb +34 -0
  115. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +64 -0
  116. data/spec/fear/extractor/value_matcher_number_spec.rb +79 -0
  117. data/spec/fear/extractor/value_matcher_string_spec.rb +88 -0
  118. data/spec/fear/extractor/value_matcher_symbol_spec.rb +71 -0
  119. data/spec/fear/extractor_api_spec.rb +115 -0
  120. data/spec/fear/extractor_spec.rb +61 -0
  121. data/spec/fear/failure_spec.rb +145 -45
  122. data/spec/fear/for_spec.rb +57 -67
  123. data/spec/fear/future_spec.rb +691 -0
  124. data/spec/fear/guard_spec.rb +103 -0
  125. data/spec/fear/left_spec.rb +112 -46
  126. data/spec/fear/none_spec.rb +114 -16
  127. data/spec/fear/option/mixin_spec.rb +39 -0
  128. data/spec/fear/option_pattern_match_spec.rb +35 -0
  129. data/spec/fear/option_pattern_matching_spec.rb +34 -0
  130. data/spec/fear/option_spec.rb +121 -8
  131. data/spec/fear/partial_function/empty_spec.rb +38 -0
  132. data/spec/fear/partial_function_and_then_spec.rb +147 -0
  133. data/spec/fear/partial_function_composition_spec.rb +82 -0
  134. data/spec/fear/partial_function_or_else_spec.rb +276 -0
  135. data/spec/fear/partial_function_spec.rb +239 -0
  136. data/spec/fear/pattern_match_spec.rb +93 -0
  137. data/spec/fear/pattern_matching_api_spec.rb +31 -0
  138. data/spec/fear/promise_spec.rb +96 -0
  139. data/spec/fear/right_biased/left.rb +29 -32
  140. data/spec/fear/right_biased/right.rb +51 -54
  141. data/spec/fear/right_spec.rb +109 -41
  142. data/spec/fear/some_spec.rb +80 -15
  143. data/spec/fear/success_spec.rb +99 -32
  144. data/spec/fear/try/mixin_spec.rb +19 -0
  145. data/spec/fear/try_pattern_match_spec.rb +37 -0
  146. data/spec/fear/try_pattern_matching_spec.rb +34 -0
  147. data/spec/fear/utils_spec.rb +16 -14
  148. data/spec/spec_helper.rb +13 -7
  149. data/spec/struct_pattern_matching_spec.rb +36 -0
  150. data/spec/struct_spec.rb +226 -0
  151. data/spec/support/dry_types.rb +6 -0
  152. metadata +320 -29
  153. data/.travis.yml +0 -9
  154. data/lib/fear/done.rb +0 -22
  155. data/lib/fear/for/evaluation_context.rb +0 -91
data/Rakefile CHANGED
@@ -1 +1,369 @@
1
- require 'bundler/gem_tasks'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "benchmark/ips"
5
+ require_relative "lib/fear"
6
+
7
+ namespace :perf do
8
+ # Contains benchmarking against Dry-rb
9
+ namespace :dry do
10
+ task :some_fmap_vs_fear_some_map do
11
+ require "dry/monads/maybe"
12
+
13
+ dry = Dry::Monads::Some.new(42)
14
+ fear = Fear.some(42)
15
+
16
+ Benchmark.ips do |x|
17
+ x.report("Dry") { dry.fmap(&:itself) }
18
+
19
+ x.report("Fear") { fear.map(&:itself) }
20
+
21
+ x.compare!
22
+ end
23
+ end
24
+
25
+ task :do_vs_fear_for do
26
+ require "dry/monads/maybe"
27
+ require "dry/monads/do"
28
+
29
+ class Operation
30
+ include Dry::Monads::Maybe::Mixin
31
+ include Dry::Monads::Do.for(:call)
32
+
33
+ def call
34
+ m1 = Some(1)
35
+ m2 = Some(2)
36
+
37
+ one = yield m1
38
+ two = yield m2
39
+
40
+ Some(one + two)
41
+ end
42
+ end
43
+
44
+ op = Operation.new
45
+
46
+ Benchmark.ips do |x|
47
+ x.report("Dry") { op.() }
48
+
49
+ x.report("Fear") do |_n|
50
+ Fear.for(Fear.some(1), Fear.some(2)) do |one, two|
51
+ one + two
52
+ end
53
+ end
54
+
55
+ x.compare!
56
+ end
57
+ end
58
+ end
59
+
60
+ # Contains internal benchmarking to if optimization works
61
+ namespace :fear do
62
+ task :fear_pattern_extracting_with_vs_without_cache do
63
+ some = Fear.some([:err, "not found"])
64
+
65
+ class WOCache < Fear::Extractor::Pattern
66
+ def initialize(pattern)
67
+ @matcher = compile_pattern_without_cache(pattern)
68
+ end
69
+ end
70
+ pattern = "Fear::Some([:err, code])"
71
+
72
+ Benchmark.ips do |x|
73
+ x.report("With cache") do |_n|
74
+ Fear::Extractor::Pattern.new(pattern).extracted_arguments(some)
75
+ end
76
+
77
+ x.report("Without cache") do |_n|
78
+ WOCache.new(pattern).extracted_arguments(some)
79
+ end
80
+
81
+ x.compare!
82
+ end
83
+ end
84
+
85
+ namespace :guard do
86
+ task :and1_vs_new do
87
+ condition = Integer
88
+
89
+ Benchmark.ips do |x|
90
+ x.report("Guard.new") do |n|
91
+ Fear::PartialFunction::Guard.new(condition) === n
92
+ end
93
+
94
+ x.report("Guard.and1") do |n|
95
+ Fear::PartialFunction::Guard.and1(condition) === n
96
+ end
97
+
98
+ x.compare!
99
+ end
100
+ end
101
+
102
+ task :and2_vs_and do
103
+ first = Integer
104
+ second = ->(x) { x > 2 }
105
+
106
+ and2 = Fear::PartialFunction::Guard.and2(first, second)
107
+ and_and = Fear::PartialFunction::Guard.new(first).and(Fear::PartialFunction::Guard.new(second))
108
+
109
+ Benchmark.ips do |x|
110
+ x.report("and2") do |n|
111
+ and2 === n
112
+ end
113
+
114
+ x.report("Guard#and") do |n|
115
+ and_and === n
116
+ end
117
+
118
+ x.compare!
119
+ end
120
+ end
121
+
122
+ task :and3_vs_and_and do
123
+ first = Integer
124
+ second = ->(x) { x > 2 }
125
+ third = ->(x) { x < 10 }
126
+
127
+ and3 = Fear::PartialFunction::Guard.and3(first, second, third)
128
+
129
+ and_and_and = Fear::PartialFunction::Guard.new(first)
130
+ .and(Fear::PartialFunction::Guard.new(second))
131
+ .and(Fear::PartialFunction::Guard.new(third))
132
+
133
+ Benchmark.ips do |x|
134
+ x.report("Guard.and3") do |n|
135
+ and3 === n
136
+ end
137
+
138
+ x.report("Guard#and") do |n|
139
+ and_and_and === n
140
+ end
141
+
142
+ x.compare!
143
+ end
144
+ end
145
+ end
146
+
147
+ task :pattern_matching_construction_vs_execution do
148
+ matcher = Fear::PatternMatch.new do |m|
149
+ m.case(Integer) { |x| x * 2 }
150
+ m.case(String) { |x| x.to_i(10) * 2 }
151
+ end
152
+
153
+ Benchmark.ips do |x|
154
+ x.report("construction") do
155
+ Fear::PatternMatch.new do |m|
156
+ m.case(Integer) { |y| y * 2 }
157
+ m.case(String) { |y| y.to_i(10) * 2 }
158
+ end
159
+ end
160
+
161
+ x.report("execution") do
162
+ matcher.(42)
163
+ end
164
+
165
+ x.compare!
166
+ end
167
+ end
168
+ end
169
+
170
+ namespace :pattern_matching do
171
+ require "qo"
172
+ require "dry/matcher"
173
+
174
+ task :option_match_vs_native_pattern_match do
175
+ some = Fear.some(42)
176
+
177
+ Benchmark.ips do |x|
178
+ x.report("case ... in ...") do
179
+ case some
180
+ in Fear::Some(41 => x)
181
+ x
182
+ in Fear::Some(42 => x)
183
+ x
184
+ in Fear::Some(43 => x)
185
+ x
186
+ end
187
+ end
188
+
189
+ x.report("Option.match") do
190
+ some.match do |m|
191
+ m.some(41, &:itself)
192
+ m.some(42, &:itself)
193
+ m.some(45, &:itself)
194
+ end
195
+ end
196
+
197
+ x.compare!
198
+ end
199
+ end
200
+
201
+ task :qo_vs_fear_pattern_extraction do
202
+ User = Struct.new(:id, :name)
203
+ user = User.new(42, "Jane")
204
+
205
+ Benchmark.ips do |x|
206
+ x.report("Qo") do
207
+ Qo.case(user, destructure: true) do |m|
208
+ m.when(User) { |id, name| [id, name] }
209
+ end
210
+ end
211
+
212
+ x.report("Fear") do
213
+ Fear.match(user) do |m|
214
+ m.xcase("User(id, name)") { |id:, name:| [id, name] }
215
+ end
216
+ end
217
+
218
+ x.compare!
219
+ end
220
+ end
221
+
222
+ task :dry_vs_qo_vs_fear_try do
223
+ module ExhaustivePatternMatch
224
+ def initialize(*)
225
+ super
226
+ @default ||= self.else { raise Fear::MatchError }
227
+ end
228
+ end
229
+
230
+ SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
231
+ FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
232
+
233
+ PatternMatch = Qo.create_pattern_match(
234
+ branches: [SuccessBranch, FailureBranch],
235
+ ).prepend(ExhaustivePatternMatch)
236
+
237
+ Fear::Success.include(PatternMatch.mixin(as: :qo_match))
238
+
239
+ success_case = Dry::Matcher::Case.new(
240
+ match: ->(try, *pattern) {
241
+ try.is_a?(Fear::Success) && pattern.all? { |p| p === try.get }
242
+ },
243
+ resolve: ->(try) { try.get },
244
+ )
245
+
246
+ failure_case = Dry::Matcher::Case.new(
247
+ match: ->(try, *pattern) {
248
+ try.is_a?(Fear::Failure) && pattern.all? { |p| p === try.exception }
249
+ },
250
+ resolve: ->(value) { value.exception },
251
+ )
252
+
253
+ # Build the matcher
254
+ matcher = Dry::Matcher.new(success: success_case, failure: failure_case)
255
+
256
+ success = Fear::Success.new(4)
257
+
258
+ Benchmark.ips do |x|
259
+ x.report("Qo") do
260
+ success.qo_match do |m|
261
+ m.failure(&:itself)
262
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
263
+ m.success { "else" }
264
+ end
265
+ end
266
+
267
+ x.report("Fear") do
268
+ success.match do |m|
269
+ m.failure(&:itself)
270
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
271
+ m.success { "else" }
272
+ end
273
+ end
274
+
275
+ x.report("Dr::Matcher") do
276
+ matcher.(success) do |m|
277
+ m.failure(&:itself)
278
+ m.success(Integer, ->(y) { y % 5 == 0 }, &:itself)
279
+ m.success { "else" }
280
+ end
281
+ end
282
+
283
+ x.compare!
284
+ end
285
+ end
286
+
287
+ task :qo_vs_fear_try_execution do
288
+ module ExhaustivePatternMatch
289
+ def initialize(*)
290
+ super
291
+ @default ||= self.else { raise Fear::MatchError }
292
+ end
293
+ end
294
+
295
+ SuccessBranch = Qo.create_branch(name: "success", precondition: Fear::Success, extractor: :get)
296
+ FailureBranch = Qo.create_branch(name: "failure", precondition: Fear::Failure, extractor: :exception)
297
+
298
+ QoPatternMatch = Qo.create_pattern_match(
299
+ branches: [SuccessBranch, FailureBranch],
300
+ ).prepend(ExhaustivePatternMatch)
301
+
302
+ Fear::Success.include(QoPatternMatch.mixin(as: :qo_match))
303
+
304
+ success = Fear::Success.new(4)
305
+
306
+ qo_matcher = QoPatternMatch.new do |m|
307
+ m.success(1, &:itself)
308
+ m.success(4, &:itself)
309
+ m.failure { "failure" }
310
+ end
311
+
312
+ fear_matcher = Fear::TryPatternMatch.new do |m|
313
+ m.success(1, &:itself)
314
+ m.success(4, &:itself)
315
+ m.failure { "failure" }
316
+ end
317
+
318
+ Benchmark.ips do |x|
319
+ x.report("Qo") do
320
+ qo_matcher.(success)
321
+ end
322
+
323
+ x.report("Fear") do
324
+ fear_matcher.(success)
325
+ end
326
+
327
+ x.compare!
328
+ end
329
+ end
330
+
331
+ task :factorial do
332
+ factorial_proc = proc do |n|
333
+ if n <= 1
334
+ 1
335
+ else
336
+ n * factorial_proc.(n - 1)
337
+ end
338
+ end
339
+
340
+ factorial_pm = Fear.matcher do |m|
341
+ m.case(1, &:itself)
342
+ m.case(0, &:itself)
343
+ m.else { |n| n * factorial_pm.(n - 1) }
344
+ end
345
+
346
+ factorial_qo = Qo.match do |m|
347
+ m.when(1, &:itself)
348
+ m.when(0, &:itself)
349
+ m.else { |n| n * factorial_qo.(n - 1) }
350
+ end
351
+
352
+ Benchmark.ips do |x|
353
+ x.report("Proc") do
354
+ factorial_proc.(100)
355
+ end
356
+
357
+ x.report("Fear") do
358
+ factorial_pm.(100)
359
+ end
360
+
361
+ x.report("Qo") do
362
+ factorial_qo.(100)
363
+ end
364
+
365
+ x.compare!
366
+ end
367
+ end
368
+ end
369
+ end
@@ -0,0 +1 @@
1
+ See Rakefile
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:dry:do_vs_fear_for
2
+ Warming up --------------------------------------
3
+ Dry 31.375k i/100ms
4
+ Fear 24.131k i/100ms
5
+ Calculating -------------------------------------
6
+ Dry 360.990k (± 2.7%) i/s - 1.820M in 5.045364s
7
+ Fear 7.212B (±27.2%) i/s - 27.210B in 4.656760s
8
+
9
+ Comparison:
10
+ Fear: 7212177713.5 i/s
11
+ Dry: 360989.8 i/s - 19978.90x slower
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:dry:some_fmap_vs_fear_some_map
2
+ Warming up --------------------------------------
3
+ Dry 68.154k i/100ms
4
+ Fear 151.093k i/100ms
5
+ Calculating -------------------------------------
6
+ Dry 884.315k (± 4.1%) i/s - 4.430M in 5.018931s
7
+ Fear 2.481M (± 4.1%) i/s - 12.390M in 5.003728s
8
+
9
+ Comparison:
10
+ Fear: 2480589.0 i/s
11
+ Dry: 884315.1 i/s - 2.81x slower
@@ -0,0 +1,16 @@
1
+ # Depends on `n`, for 100!:
2
+
3
+ > bundle exec rake perf:pattern_matching:factorial
4
+ Warming up --------------------------------------
5
+ Proc 2.395k i/100ms
6
+ Fear 312.000 i/100ms
7
+ Qo 122.000 i/100ms
8
+ Calculating -------------------------------------
9
+ Proc 26.620k (± 2.9%) i/s - 134.120k in 5.042738s
10
+ Fear 3.219k (± 4.1%) i/s - 16.224k in 5.049215s
11
+ Qo 1.250k (± 4.8%) i/s - 6.344k in 5.090745s
12
+
13
+ Comparison:
14
+ Proc: 26620.3 i/s
15
+ Fear: 3219.4 i/s - 8.27x slower
16
+ Qo: 1249.6 i/s - 21.30x slower
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with only one guard actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and1_vs_new
4
+ Warming up --------------------------------------
5
+ Guard.new 173.019k i/100ms
6
+ Guard.and1 268.379k i/100ms
7
+ Calculating -------------------------------------
8
+ Guard.new 171.291B (± 8.4%) i/s - 561.437B
9
+ Guard.and1 266.882B (± 5.9%) i/s - 751.316B
10
+
11
+ Comparison:
12
+ Guard.and1: 266881817299.6 i/s
13
+ Guard.new: 171291386467.1 i/s - 1.56x slower
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with two guards actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and2_vs_guard_and_guard
4
+ Warming up --------------------------------------
5
+ and2 224.836k i/100ms
6
+ Guard#and 211.833k i/100ms
7
+ Calculating -------------------------------------
8
+ and2 224.457B (± 3.8%) i/s - 651.564B
9
+ Guard#and 211.486B (± 3.7%) i/s - 667.936B
10
+
11
+ Comparison:
12
+ and2: 224457051906.8 i/s
13
+ Guard#and: 211485786834.4 i/s - same-ish: difference falls within error
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with three guards actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and3_vs_and_and
4
+ Warming up --------------------------------------
5
+ Guard.and3 236.318k i/100ms
6
+ Guard#and 170.369k i/100ms
7
+ Calculating -------------------------------------
8
+ Guard.and3 235.992B (± 3.4%) i/s - 791.166B
9
+ Guard#and 169.998B (± 4.0%) i/s - 640.637B
10
+
11
+ Comparison:
12
+ Guard.and3: 235992292688.6 i/s
13
+ Guard#and: 169997755111.1 i/s - 1.39x slower