flows 0.3.0 → 0.4.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{build.yml → test.yml} +5 -10
  3. data/.gitignore +1 -0
  4. data/.reek.yml +42 -0
  5. data/.rubocop.yml +20 -7
  6. data/.ruby-version +1 -1
  7. data/.yardopts +1 -0
  8. data/CHANGELOG.md +42 -0
  9. data/Gemfile +0 -6
  10. data/Gemfile.lock +139 -74
  11. data/README.md +158 -364
  12. data/Rakefile +35 -1
  13. data/bin/.rubocop.yml +5 -0
  14. data/bin/all_the_errors +47 -0
  15. data/bin/benchmark +73 -105
  16. data/bin/benchmark_cli/compare.rb +118 -0
  17. data/bin/benchmark_cli/compare/a_plus_b.rb +22 -0
  18. data/bin/benchmark_cli/compare/base.rb +45 -0
  19. data/bin/benchmark_cli/compare/command.rb +47 -0
  20. data/bin/benchmark_cli/compare/ten_steps.rb +22 -0
  21. data/bin/benchmark_cli/examples.rb +23 -0
  22. data/bin/benchmark_cli/examples/.rubocop.yml +19 -0
  23. data/bin/benchmark_cli/examples/a_plus_b/dry_do.rb +23 -0
  24. data/bin/benchmark_cli/examples/a_plus_b/dry_transaction.rb +17 -0
  25. data/bin/benchmark_cli/examples/a_plus_b/flows_do.rb +22 -0
  26. data/bin/benchmark_cli/examples/a_plus_b/flows_railway.rb +13 -0
  27. data/bin/benchmark_cli/examples/a_plus_b/flows_scp.rb +13 -0
  28. data/bin/benchmark_cli/examples/a_plus_b/flows_scp_mut.rb +13 -0
  29. data/bin/benchmark_cli/examples/a_plus_b/flows_scp_oc.rb +21 -0
  30. data/bin/benchmark_cli/examples/a_plus_b/trailblazer.rb +15 -0
  31. data/bin/benchmark_cli/examples/ten_steps/dry_do.rb +70 -0
  32. data/bin/benchmark_cli/examples/ten_steps/dry_transaction.rb +64 -0
  33. data/bin/benchmark_cli/examples/ten_steps/flows_do.rb +69 -0
  34. data/bin/benchmark_cli/examples/ten_steps/flows_railway.rb +58 -0
  35. data/bin/benchmark_cli/examples/ten_steps/flows_scp.rb +58 -0
  36. data/bin/benchmark_cli/examples/ten_steps/flows_scp_mut.rb +58 -0
  37. data/bin/benchmark_cli/examples/ten_steps/flows_scp_oc.rb +66 -0
  38. data/bin/benchmark_cli/examples/ten_steps/trailblazer.rb +60 -0
  39. data/bin/benchmark_cli/helpers.rb +12 -0
  40. data/bin/benchmark_cli/ruby.rb +15 -0
  41. data/bin/benchmark_cli/ruby/command.rb +38 -0
  42. data/bin/benchmark_cli/ruby/method_exec.rb +71 -0
  43. data/bin/benchmark_cli/ruby/self_class.rb +69 -0
  44. data/bin/benchmark_cli/ruby/structs.rb +90 -0
  45. data/bin/console +1 -0
  46. data/bin/docserver +7 -0
  47. data/bin/errors +118 -0
  48. data/bin/errors_cli/contract_error_demo.rb +49 -0
  49. data/bin/errors_cli/di_error_demo.rb +38 -0
  50. data/bin/errors_cli/flows_router_error_demo.rb +15 -0
  51. data/bin/errors_cli/oc_error_demo.rb +40 -0
  52. data/bin/errors_cli/railway_error_demo.rb +10 -0
  53. data/bin/errors_cli/result_error_demo.rb +13 -0
  54. data/bin/errors_cli/scp_error_demo.rb +17 -0
  55. data/docs/README.md +2 -186
  56. data/docs/_sidebar.md +0 -24
  57. data/docs/index.html +1 -1
  58. data/flows.gemspec +25 -2
  59. data/forspell.dict +9 -0
  60. data/lefthook.yml +9 -0
  61. data/lib/flows.rb +11 -5
  62. data/lib/flows/contract.rb +402 -0
  63. data/lib/flows/contract/array.rb +55 -0
  64. data/lib/flows/contract/case_eq.rb +41 -0
  65. data/lib/flows/contract/compose.rb +77 -0
  66. data/lib/flows/contract/either.rb +53 -0
  67. data/lib/flows/contract/error.rb +25 -0
  68. data/lib/flows/contract/hash.rb +75 -0
  69. data/lib/flows/contract/hash_of.rb +70 -0
  70. data/lib/flows/contract/helpers.rb +22 -0
  71. data/lib/flows/contract/predicate.rb +34 -0
  72. data/lib/flows/contract/transformer.rb +50 -0
  73. data/lib/flows/contract/tuple.rb +70 -0
  74. data/lib/flows/flow.rb +75 -7
  75. data/lib/flows/flow/node.rb +131 -0
  76. data/lib/flows/flow/router.rb +25 -0
  77. data/lib/flows/flow/router/custom.rb +54 -0
  78. data/lib/flows/flow/router/errors.rb +11 -0
  79. data/lib/flows/flow/router/simple.rb +20 -0
  80. data/lib/flows/plugin.rb +13 -0
  81. data/lib/flows/plugin/dependency_injector.rb +159 -0
  82. data/lib/flows/plugin/dependency_injector/dependency.rb +24 -0
  83. data/lib/flows/plugin/dependency_injector/dependency_definition.rb +16 -0
  84. data/lib/flows/plugin/dependency_injector/dependency_list.rb +57 -0
  85. data/lib/flows/plugin/dependency_injector/errors.rb +58 -0
  86. data/lib/flows/plugin/implicit_init.rb +45 -0
  87. data/lib/flows/plugin/output_contract.rb +84 -0
  88. data/lib/flows/plugin/output_contract/dsl.rb +36 -0
  89. data/lib/flows/plugin/output_contract/errors.rb +74 -0
  90. data/lib/flows/plugin/output_contract/wrapper.rb +53 -0
  91. data/lib/flows/railway.rb +140 -37
  92. data/lib/flows/railway/dsl.rb +8 -19
  93. data/lib/flows/railway/errors.rb +8 -12
  94. data/lib/flows/railway/step.rb +24 -0
  95. data/lib/flows/railway/step_list.rb +38 -0
  96. data/lib/flows/result.rb +188 -2
  97. data/lib/flows/result/do.rb +160 -16
  98. data/lib/flows/result/err.rb +12 -6
  99. data/lib/flows/result/errors.rb +29 -17
  100. data/lib/flows/result/helpers.rb +25 -3
  101. data/lib/flows/result/ok.rb +12 -6
  102. data/lib/flows/shared_context_pipeline.rb +216 -0
  103. data/lib/flows/shared_context_pipeline/dsl.rb +63 -0
  104. data/lib/flows/shared_context_pipeline/errors.rb +17 -0
  105. data/lib/flows/shared_context_pipeline/mutation_step.rb +31 -0
  106. data/lib/flows/shared_context_pipeline/router_definition.rb +21 -0
  107. data/lib/flows/shared_context_pipeline/step.rb +46 -0
  108. data/lib/flows/shared_context_pipeline/track.rb +67 -0
  109. data/lib/flows/shared_context_pipeline/track_list.rb +46 -0
  110. data/lib/flows/util.rb +17 -0
  111. data/lib/flows/util/inheritable_singleton_vars.rb +79 -0
  112. data/lib/flows/util/inheritable_singleton_vars/dup_strategy.rb +109 -0
  113. data/lib/flows/util/inheritable_singleton_vars/isolation_strategy.rb +104 -0
  114. data/lib/flows/util/prepend_to_class.rb +145 -0
  115. data/lib/flows/version.rb +1 -1
  116. metadata +233 -37
  117. data/bin/demo +0 -66
  118. data/bin/examples.rb +0 -195
  119. data/bin/profile_10steps +0 -106
  120. data/bin/ruby_benchmarks +0 -26
  121. data/docs/CNAME +0 -1
  122. data/docs/contributing/benchmarks_profiling.md +0 -3
  123. data/docs/contributing/local_development.md +0 -3
  124. data/docs/flow/direct_usage.md +0 -3
  125. data/docs/flow/general_idea.md +0 -3
  126. data/docs/operation/basic_usage.md +0 -1
  127. data/docs/operation/inject_steps.md +0 -3
  128. data/docs/operation/lambda_steps.md +0 -3
  129. data/docs/operation/result_shapes.md +0 -3
  130. data/docs/operation/routing_tracks.md +0 -3
  131. data/docs/operation/wrapping_steps.md +0 -3
  132. data/docs/overview/performance.md +0 -336
  133. data/docs/railway/basic_usage.md +0 -232
  134. data/docs/result_objects/basic_usage.md +0 -196
  135. data/docs/result_objects/do_notation.md +0 -139
  136. data/lib/flows/implicit_build.rb +0 -16
  137. data/lib/flows/node.rb +0 -27
  138. data/lib/flows/operation.rb +0 -55
  139. data/lib/flows/operation/builder.rb +0 -130
  140. data/lib/flows/operation/builder/build_router.rb +0 -37
  141. data/lib/flows/operation/dsl.rb +0 -93
  142. data/lib/flows/operation/errors.rb +0 -75
  143. data/lib/flows/operation/executor.rb +0 -78
  144. data/lib/flows/railway/builder.rb +0 -68
  145. data/lib/flows/railway/executor.rb +0 -23
  146. data/lib/flows/result_router.rb +0 -14
  147. data/lib/flows/router.rb +0 -22
data/bin/demo DELETED
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'bundler/setup'
4
- require 'flows'
5
-
6
- # Helper for demonstrations
7
- module Demo
8
- def self.run(name)
9
- puts '-' * 60
10
- puts name
11
- puts '-' * 60
12
- puts
13
-
14
- begin
15
- yield
16
- rescue StandardError => e
17
- puts "Exception raised:\n\n#{e.full_message}"
18
- end
19
- puts "\n" + '-' * 60 + "\n" * 2
20
- end
21
- end
22
-
23
- # Simple division
24
- class DivisionOperation
25
- include Flows::Operation
26
-
27
- step :check_for_zero
28
- step :divide
29
-
30
- ok_shape :result
31
- err_shape :error
32
-
33
- def check_for_zero(denominator:, **)
34
- if denominator.zero?
35
- err(error: 'Denominator cannot be zero')
36
- else
37
- ok
38
- end
39
- end
40
-
41
- def divide(numerator:, denominator:, **)
42
- ok(result: numerator / denominator)
43
- end
44
- end
45
-
46
- # Division in nested operation - we do division
47
- class NestedDivisionOperation
48
- include Flows::Operation
49
-
50
- step :do_division
51
-
52
- ok_shape :result
53
- err_shape :error
54
-
55
- def do_division(**params)
56
- DivisionOperation.new.call(**params)
57
- end
58
- end
59
-
60
- Demo.run 'Unwrap Error verbosity' do
61
- DivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
62
- end
63
-
64
- Demo.run 'Unwrap Error verbosity when error happened in nested operation' do
65
- NestedDivisionOperation.new.call(numerator: 1, denominator: 0).unwrap[:result]
66
- end
@@ -1,195 +0,0 @@
1
- # rubocop:disable all
2
- require 'flows'
3
- require 'dry/transaction'
4
- require 'trailblazer/operation'
5
-
6
- #
7
- # Task: a + b = ?
8
- #
9
-
10
- class FlowsSummator
11
- include Flows::Operation
12
-
13
- step :sum
14
-
15
- ok_shape :sum
16
-
17
- def sum(a:, b:, **)
18
- ok(sum: a + b)
19
- end
20
- end
21
-
22
- class FlowsRailwaySummator
23
- include Flows::Railway
24
-
25
- step :sum
26
-
27
- def sum(a:, b:)
28
- ok(sum: a + b)
29
- end
30
- end
31
-
32
- class POROSummator
33
- def self.call(a:, b:)
34
- a + b
35
- end
36
- end
37
-
38
- class DrySummator
39
- include Dry::Transaction
40
-
41
- step :sum
42
-
43
- private
44
-
45
- def sum(a:, b:)
46
- Success(a + b)
47
- end
48
- end
49
-
50
- class TBSummator < Trailblazer::Operation
51
- step :sum
52
-
53
- def sum(opts, a:, b:, **)
54
- opts[:sum] = a + b
55
- end
56
- end
57
-
58
- #
59
- # Task: 10 steps which returns simple value
60
- #
61
-
62
- class FlowsTenSteps
63
- include Flows::Operation
64
-
65
- step :s1
66
- step :s2
67
- step :s3
68
- step :s4
69
- step :s5
70
- step :s6
71
- step :s7
72
- step :s8
73
- step :s9
74
- step :s10
75
-
76
- ok_shape :data
77
-
78
- def s1(**); ok(s1: true); end
79
- def s2(**); ok(s2: true); end
80
- def s3(**); ok(s3: true); end
81
- def s4(**); ok(s4: true); end
82
- def s5(**); ok(s5: true); end
83
- def s5(**); ok(s5: true); end
84
- def s6(**); ok(s6: true); end
85
- def s7(**); ok(s7: true); end
86
- def s8(**); ok(s8: true); end
87
- def s9(**); ok(s9: true); end
88
- def s10(**); ok(data: :ok); end
89
- end
90
-
91
- class FlowsRailwayTenSteps
92
- include Flows::Railway
93
-
94
- step :s1
95
- step :s2
96
- step :s3
97
- step :s4
98
- step :s5
99
- step :s6
100
- step :s7
101
- step :s8
102
- step :s9
103
- step :s10
104
-
105
- def s1(**); ok(s1: true); end
106
- def s2(s1:); ok(s2: s1); end
107
- def s3(s2:); ok(s3: s2); end
108
- def s4(s3:); ok(s4: s3); end
109
- def s5(s4:); ok(s5: s4); end
110
- def s6(s5:); ok(s6: s5); end
111
- def s7(s6:); ok(s7: s6); end
112
- def s8(s7:); ok(s8: s7); end
113
- def s9(s8:); ok(s9: s8); end
114
- def s10(s9:); ok(data: :ok); end
115
- end
116
-
117
- class POROTenSteps
118
- class << self
119
- def call()
120
- s1
121
- s2
122
- s3
123
- s4
124
- s5
125
- s6
126
- s7
127
- s8
128
- s9
129
- s10
130
- end
131
-
132
- def s1; true; end
133
- def s2; true; end
134
- def s3; true; end
135
- def s4; true; end
136
- def s5; true; end
137
- def s6; true; end
138
- def s7; true; end
139
- def s8; true; end
140
- def s9; true; end
141
- def s10; true; end
142
- end
143
- end
144
-
145
- class DryTenSteps
146
- include Dry::Transaction
147
-
148
- step :s1
149
- step :s2
150
- step :s3
151
- step :s4
152
- step :s5
153
- step :s6
154
- step :s7
155
- step :s8
156
- step :s9
157
- step :s10
158
-
159
- private
160
-
161
- def s1; Success(true); end
162
- def s2; Success(true); end
163
- def s3; Success(true); end
164
- def s4; Success(true); end
165
- def s5; Success(true); end
166
- def s6; Success(true); end
167
- def s7; Success(true); end
168
- def s8; Success(true); end
169
- def s9; Success(true); end
170
- def s10; Success(true); end
171
- end
172
-
173
- class TBTenSteps < Trailblazer::Operation
174
- step :s1
175
- step :s2
176
- step :s3
177
- step :s4
178
- step :s5
179
- step :s6
180
- step :s7
181
- step :s8
182
- step :s9
183
- step :s10
184
-
185
- def s1(opts, **); opts[:s1] = true; end
186
- def s2(opts, **); opts[:s2] = true; end
187
- def s3(opts, **); opts[:s3] = true; end
188
- def s4(opts, **); opts[:s4] = true; end
189
- def s5(opts, **); opts[:s5] = true; end
190
- def s6(opts, **); opts[:s6] = true; end
191
- def s7(opts, **); opts[:s7] = true; end
192
- def s8(opts, **); opts[:s8] = true; end
193
- def s9(opts, **); opts[:s9] = true; end
194
- def s10(opts, **); opts[:s10] = true; end
195
- end
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # rubocop:disable all
3
-
4
- require 'bundler/setup'
5
- require 'json'
6
- require 'ruby-prof'
7
- require 'stackprof'
8
-
9
- require_relative './examples'
10
-
11
- flows_ten_steps = FlowsTenSteps.new
12
- flows_railway_ten_steps = FlowsRailwayTenSteps.new
13
-
14
- build_output_name = '10steps_build_10k_times'
15
- exec_output_name = '10steps_execution_10k_times'
16
-
17
- #
18
- # RubyProf
19
- #
20
- RubyProf.measure_mode = RubyProf::WALL_TIME
21
-
22
-
23
- puts 'Build with RubyProf...'
24
-
25
- result = RubyProf.profile do
26
- 10_000.times do
27
- FlowsTenSteps.new
28
- end
29
- end
30
- printer = RubyProf::MultiPrinter.new(result)
31
- printer.print(path: 'profile', profile: "#{build_output_name}_operaion")
32
-
33
- result = RubyProf.profile do
34
- 10_000.times do
35
- FlowsRailwayTenSteps.new
36
- end
37
- end
38
- printer = RubyProf::MultiPrinter.new(result)
39
- printer.print(path: 'profile', profile: "#{build_output_name}_railway")
40
-
41
-
42
- puts 'Execution with RubyProf...'
43
-
44
- result = RubyProf.profile do
45
- 10_000.times {
46
- flows_ten_steps.call
47
- }
48
- end
49
- printer = RubyProf::MultiPrinter.new(result)
50
- printer.print(path: 'profile', profile: "#{exec_output_name}_operation")
51
-
52
- result = RubyProf.profile do
53
- 10_000.times {
54
- flows_railway_ten_steps.call
55
- }
56
- end
57
- printer = RubyProf::MultiPrinter.new(result)
58
- printer.print(path: 'profile', profile: "#{exec_output_name}_railway")
59
-
60
-
61
- #
62
- # StackProf
63
- #
64
-
65
- puts 'Build with StackProf...'
66
-
67
- result = StackProf.run(mode: :wall, raw: true) do
68
- 10_000.times do
69
- FlowsTenSteps.new
70
- end
71
- end
72
- File.write("profile/#{build_output_name}_operation.json", JSON.generate(result))
73
-
74
- result = StackProf.run(mode: :wall, raw: true) do
75
- 10_000.times do
76
- FlowsRailwayTenSteps.new
77
- end
78
- end
79
- File.write("profile/#{build_output_name}_railway.json", JSON.generate(result))
80
-
81
-
82
- puts 'Execution with StackProf...'
83
-
84
- result = StackProf.run(mode: :wall, raw: true) do
85
- 10_000.times do
86
- flows_ten_steps.call
87
- end
88
- end
89
- File.write("profile/#{exec_output_name}_operation.json", JSON.generate(result))
90
-
91
- result = StackProf.run(mode: :wall, raw: true) do
92
- 10_000.times do
93
- flows_railway_ten_steps.call
94
- end
95
- end
96
- File.write("profile/#{exec_output_name}_railway.json", JSON.generate(result))
97
-
98
-
99
- puts
100
- puts 'Install speedscope:'
101
- puts ' npm i -g speedscope'
102
- puts
103
- puts "speedscope profile/#{build_output_name}_operation.json"
104
- puts "speedscope profile/#{build_output_name}_railway.json"
105
- puts "speedscope profile/#{exec_output_name}_operation.json"
106
- puts "speedscope profile/#{exec_output_name}_railway.json"
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # rubocop:disable all
3
-
4
- require 'bundler/setup'
5
- require 'benchmark/ips'
6
-
7
- puts '-' * 50
8
- puts '- method execution'
9
- puts '-' * 50
10
-
11
- class OneMethod
12
- def meth
13
- :ok
14
- end
15
- end
16
-
17
- one_method = OneMethod.new
18
- method_obj = one_method.method(:meth)
19
-
20
- Benchmark.ips do |b|
21
- b.report('native call') { one_method.meth }
22
- b.report('send(...)') { one_method.send(:meth) }
23
- b.report('Method#call') { method_obj.call }
24
-
25
- b.compare!
26
- end
data/docs/CNAME DELETED
@@ -1 +0,0 @@
1
- flows.ffloyd.tech
@@ -1,3 +0,0 @@
1
- # Benchmarks & Profiling
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Local Development
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Direct Usage
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # General Idea
2
-
3
- TODO
@@ -1 +0,0 @@
1
- # Basic Usage
@@ -1,3 +0,0 @@
1
- # Inject Steps
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Lambda Steps
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Result Shapes
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Routing & Tracks
2
-
3
- TODO
@@ -1,3 +0,0 @@
1
- # Wrapping Steps
2
-
3
- TODO
@@ -1,336 +0,0 @@
1
- # Performance
2
-
3
- Host:
4
-
5
- * MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
6
- * 3.1 GHz Intel Core i5
7
- * 8 GB 2133 MHz LPDDR3
8
-
9
- ## Comparison with Trailblazer
10
-
11
- `Flows::Railway` does not support tracks and routes, so it's reasonable to compare with `Flows::Operation` only.
12
-
13
- `WITH_OP=1 WITH_TB=1 bin/benchmark` results:
14
-
15
- ```
16
- --------------------------------------------------
17
- - task: A + B, one step implementation
18
- --------------------------------------------------
19
- Warming up --------------------------------------
20
- Flows::Operation (build once)
21
- 25.356k i/100ms
22
- Flows::Operation (build each time)
23
- 9.168k i/100ms
24
- Trailblazer::Operation
25
- 5.016k i/100ms
26
- Calculating -------------------------------------
27
- Flows::Operation (build once)
28
- 277.460k (± 1.2%) i/s - 1.395M in 5.027011s
29
- Flows::Operation (build each time)
30
- 95.740k (± 2.7%) i/s - 485.904k in 5.079226s
31
- Trailblazer::Operation
32
- 52.975k (± 1.8%) i/s - 265.848k in 5.020109s
33
-
34
- Comparison:
35
- Flows::Operation (build once): 277459.5 i/s
36
- Flows::Operation (build each time): 95739.6 i/s - 2.90x slower
37
- Trailblazer::Operation: 52974.6 i/s - 5.24x slower
38
-
39
-
40
- --------------------------------------------------
41
- - task: ten steps returns successful result
42
- --------------------------------------------------
43
- Warming up --------------------------------------
44
- Flows::Operation (build once)
45
- 3.767k i/100ms
46
- Flows::Operation (build each time)
47
- 1.507k i/100ms
48
- Trailblazer::Operation
49
- 1.078k i/100ms
50
- Calculating -------------------------------------
51
- Flows::Operation (build once)
52
- 37.983k (± 2.9%) i/s - 192.117k in 5.062658s
53
- Flows::Operation (build each time)
54
- 14.991k (± 4.2%) i/s - 75.350k in 5.035443s
55
- Trailblazer::Operation
56
- 10.897k (± 2.8%) i/s - 54.978k in 5.049665s
57
-
58
- Comparison:
59
- Flows::Operation (build once): 37982.8 i/s
60
- Flows::Operation (build each time): 14990.6 i/s - 2.53x slower
61
- Trailblazer::Operation: 10896.9 i/s - 3.49x slower
62
- ```
63
-
64
- ## Comparison with Dry::Transaction
65
-
66
- `Dry::Transaction` does not support tracks and branching so it's reasonable to compare with `Flows::Railway` only.
67
-
68
- `WITH_RW=1 WITH_DRY=1 bin/benchmark` results:
69
-
70
- ```
71
- --------------------------------------------------
72
- - task: A + B, one step implementation
73
- --------------------------------------------------
74
- Warming up --------------------------------------
75
- Flows::Railway (build once)
76
- 29.324k i/100ms
77
- Flows::Railway (build each time)
78
- 11.159k i/100ms
79
- Dry::Transaction (build once)
80
- 21.480k i/100ms
81
- Dry::Transaction (build each time)
82
- 2.268k i/100ms
83
- Calculating -------------------------------------
84
- Flows::Railway (build once)
85
- 321.837k (± 1.3%) i/s - 1.613M in 5.012156s
86
- Flows::Railway (build each time)
87
- 115.743k (± 2.6%) i/s - 580.268k in 5.016961s
88
- Dry::Transaction (build once)
89
- 231.712k (± 1.7%) i/s - 1.160M in 5.007401s
90
- Dry::Transaction (build each time)
91
- 23.093k (± 2.5%) i/s - 115.668k in 5.012311s
92
-
93
- Comparison:
94
- Flows::Railway (build once): 321837.4 i/s
95
- Dry::Transaction (build once): 231712.5 i/s - 1.39x slower
96
- Flows::Railway (build each time): 115743.1 i/s - 2.78x slower
97
- Dry::Transaction (build each time): 23093.2 i/s - 13.94x slower
98
-
99
-
100
- --------------------------------------------------
101
- - task: ten steps returns successful result
102
- --------------------------------------------------
103
- Warming up --------------------------------------
104
- Flows::Railway (build once)
105
- 5.607k i/100ms
106
- Flows::Railway (build each time)
107
- 2.014k i/100ms
108
- Dry::Transaction (build once)
109
- 2.918k i/100ms
110
- Dry::Transaction (build each time)
111
- 275.000 i/100ms
112
- Calculating -------------------------------------
113
- Flows::Railway (build once)
114
- 57.765k (± 1.4%) i/s - 291.564k in 5.048484s
115
- Flows::Railway (build each time)
116
- 20.413k (± 1.2%) i/s - 102.714k in 5.032467s
117
- Dry::Transaction (build once)
118
- 29.597k (± 1.5%) i/s - 148.818k in 5.029422s
119
- Dry::Transaction (build each time)
120
- 2.753k (± 2.0%) i/s - 14.025k in 5.096279s
121
-
122
- Comparison:
123
- Flows::Railway (build once): 57765.2 i/s
124
- Dry::Transaction (build once): 29596.6 i/s - 1.95x slower
125
- Flows::Railway (build each time): 20413.0 i/s - 2.83x slower
126
- Dry::Transaction (build each time): 2753.2 i/s - 20.98x slower
127
- ```
128
-
129
- ## Railway vs Operation
130
-
131
- `Flows::Railway` is created to improve performance in situations when you don't need tracks, branching and shape control (`Flows::Operation` has this features). So, it should be faster than `Flows::Operation`.
132
-
133
- `WITH_OP=1 WITH_RW=1 bin/benchmark` results:
134
-
135
- ```
136
- --------------------------------------------------
137
- - task: A + B, one step implementation
138
- --------------------------------------------------
139
- Warming up --------------------------------------
140
- Flows::Railway (build once)
141
- 29.440k i/100ms
142
- Flows::Railway (build each time)
143
- 11.236k i/100ms
144
- Flows::Operation (build once)
145
- 25.584k i/100ms
146
- Flows::Operation (build each time)
147
- 9.161k i/100ms
148
- Calculating -------------------------------------
149
- Flows::Railway (build once)
150
- 315.648k (± 8.1%) i/s - 1.590M in 5.078736s
151
- Flows::Railway (build each time)
152
- 117.747k (± 3.5%) i/s - 595.508k in 5.064191s
153
- Flows::Operation (build once)
154
- 266.888k (±12.3%) i/s - 1.279M in 5.090531s
155
- Flows::Operation (build each time)
156
- 91.424k (±11.0%) i/s - 458.050k in 5.097449s
157
-
158
- Comparison:
159
- Flows::Railway (build once): 315647.6 i/s
160
- Flows::Operation (build once): 266888.4 i/s - same-ish: difference falls within error
161
- Flows::Railway (build each time): 117747.2 i/s - 2.68x slower
162
- Flows::Operation (build each time): 91423.7 i/s - 3.45x slower
163
-
164
-
165
- --------------------------------------------------
166
- - task: ten steps returns successful result
167
- --------------------------------------------------
168
- Warming up --------------------------------------
169
- Flows::Railway (build once)
170
- 5.619k i/100ms
171
- Flows::Railway (build each time)
172
- 2.009k i/100ms
173
- Flows::Operation (build once)
174
- 3.650k i/100ms
175
- Flows::Operation (build each time)
176
- 1.472k i/100ms
177
- Calculating -------------------------------------
178
- Flows::Railway (build once)
179
- 58.454k (± 2.8%) i/s - 292.188k in 5.002833s
180
- Flows::Railway (build each time)
181
- 20.310k (± 2.4%) i/s - 102.459k in 5.047579s
182
- Flows::Operation (build once)
183
- 38.556k (± 2.5%) i/s - 193.450k in 5.020871s
184
- Flows::Operation (build each time)
185
- 15.222k (± 2.8%) i/s - 76.544k in 5.032272s
186
-
187
- Comparison:
188
- Flows::Railway (build once): 58453.8 i/s
189
- Flows::Operation (build once): 38556.5 i/s - 1.52x slower
190
- Flows::Railway (build each time): 20310.3 i/s - 2.88x slower
191
- Flows::Operation (build each time): 15221.9 i/s - 3.84x slower
192
- ```
193
-
194
- ## Comparison with Plan Old Ruby Object
195
-
196
- Of course, `flows` cannot be faster than naive implementation without any library usage. But it's nice to know how big infrastructure cost you pay.
197
-
198
- `WITH_RW=1 WITH_PORO=1 bin/benchmark` results:
199
-
200
- ```
201
- --------------------------------------------------
202
- - task: A + B, one step implementation
203
- --------------------------------------------------
204
- Warming up --------------------------------------
205
- Flows::Railway (build once)
206
- 29.276k i/100ms
207
- Flows::Railway (build each time)
208
- 11.115k i/100ms
209
- PORO 309.108k i/100ms
210
- Calculating -------------------------------------
211
- Flows::Railway (build once)
212
- 320.587k (± 3.5%) i/s - 1.610M in 5.029314s
213
- Flows::Railway (build each time)
214
- 118.108k (± 3.0%) i/s - 600.210k in 5.086844s
215
- PORO 9.998M (± 2.1%) i/s - 50.075M in 5.010848s
216
-
217
- Comparison:
218
- PORO: 9998276.0 i/s
219
- Flows::Railway (build once): 320586.8 i/s - 31.19x slower
220
- Flows::Railway (build each time): 118108.5 i/s - 84.65x slower
221
-
222
-
223
- --------------------------------------------------
224
- - task: ten steps returns successful result
225
- --------------------------------------------------
226
- Warming up --------------------------------------
227
- Flows::Railway (build once)
228
- 5.671k i/100ms
229
- Flows::Railway (build each time)
230
- 2.024k i/100ms
231
- PORO 233.375k i/100ms
232
- Calculating -------------------------------------
233
- Flows::Railway (build once)
234
- 58.428k (± 1.6%) i/s - 294.892k in 5.048387s
235
- Flows::Railway (build each time)
236
- 20.388k (± 3.9%) i/s - 103.224k in 5.070844s
237
- PORO 4.937M (± 0.6%) i/s - 24.738M in 5.010488s
238
-
239
- Comparison:
240
- PORO: 4937372.3 i/s
241
- Flows::Railway (build once): 58428.4 i/s - 84.50x slower
242
- Flows::Railway (build each time): 20387.7 i/s - 242.17x slower
243
- ```
244
-
245
- ## All without PORO
246
-
247
- `WITH_ALL=1 bin/benchmark` results:
248
-
249
- ```
250
- --------------------------------------------------
251
- - task: A + B, one step implementation
252
- --------------------------------------------------
253
- Warming up --------------------------------------
254
- Flows::Railway (build once)
255
- 29.351k i/100ms
256
- Flows::Railway (build each time)
257
- 11.044k i/100ms
258
- Flows::Operation (build once)
259
- 25.475k i/100ms
260
- Flows::Operation (build each time)
261
- 8.989k i/100ms
262
- Dry::Transaction (build once)
263
- 21.082k i/100ms
264
- Dry::Transaction (build each time)
265
- 2.272k i/100ms
266
- Trailblazer::Operation
267
- 4.962k i/100ms
268
- Calculating -------------------------------------
269
- Flows::Railway (build once)
270
- 299.326k (±15.6%) i/s - 1.409M in 5.012398s
271
- Flows::Railway (build each time)
272
- 116.186k (± 3.1%) i/s - 585.332k in 5.042902s
273
- Flows::Operation (build once)
274
- 276.980k (± 3.1%) i/s - 1.401M in 5.064018s
275
- Flows::Operation (build each time)
276
- 94.536k (± 2.6%) i/s - 476.417k in 5.042967s
277
- Dry::Transaction (build once)
278
- 229.750k (± 1.6%) i/s - 1.160M in 5.048211s
279
- Dry::Transaction (build each time)
280
- 23.381k (± 1.9%) i/s - 118.144k in 5.054920s
281
- Trailblazer::Operation
282
- 50.936k (± 4.4%) i/s - 258.024k in 5.075897s
283
-
284
- Comparison:
285
- Flows::Railway (build once): 299325.9 i/s
286
- Flows::Operation (build once): 276979.8 i/s - same-ish: difference falls within error
287
- Dry::Transaction (build once): 229749.5 i/s - 1.30x slower
288
- Flows::Railway (build each time): 116185.6 i/s - 2.58x slower
289
- Flows::Operation (build each time): 94536.3 i/s - 3.17x slower
290
- Trailblazer::Operation: 50936.0 i/s - 5.88x slower
291
- Dry::Transaction (build each time): 23380.8 i/s - 12.80x slower
292
-
293
-
294
- --------------------------------------------------
295
- - task: ten steps returns successful result
296
- --------------------------------------------------
297
- Warming up --------------------------------------
298
- Flows::Railway (build once)
299
- 5.734k i/100ms
300
- Flows::Railway (build each time)
301
- 2.064k i/100ms
302
- Flows::Operation (build once)
303
- 3.801k i/100ms
304
- Flows::Operation (build each time)
305
- 1.502k i/100ms
306
- Dry::Transaction (build once)
307
- 2.837k i/100ms
308
- Dry::Transaction (build each time)
309
- 274.000 i/100ms
310
- Trailblazer::Operation
311
- 1.079k i/100ms
312
- Calculating -------------------------------------
313
- Flows::Railway (build once)
314
- 58.541k (± 1.6%) i/s - 298.168k in 5.094712s
315
- Flows::Railway (build each time)
316
- 20.626k (± 3.0%) i/s - 103.200k in 5.008021s
317
- Flows::Operation (build once)
318
- 38.906k (± 2.7%) i/s - 197.652k in 5.084184s
319
- Flows::Operation (build each time)
320
- 14.351k (±12.2%) i/s - 70.594k in 5.011606s
321
- Dry::Transaction (build once)
322
- 29.588k (± 1.8%) i/s - 150.361k in 5.083603s
323
- Dry::Transaction (build each time)
324
- 2.765k (± 1.8%) i/s - 13.974k in 5.054977s
325
- Trailblazer::Operation
326
- 10.861k (± 2.1%) i/s - 55.029k in 5.069204s
327
-
328
- Comparison:
329
- Flows::Railway (build once): 58541.4 i/s
330
- Flows::Operation (build once): 38906.4 i/s - 1.50x slower
331
- Dry::Transaction (build once): 29587.8 i/s - 1.98x slower
332
- Flows::Railway (build each time): 20626.0 i/s - 2.84x slower
333
- Flows::Operation (build each time): 14351.1 i/s - 4.08x slower
334
- Trailblazer::Operation: 10860.9 i/s - 5.39x slower
335
- Dry::Transaction (build each time): 2765.3 i/s - 21.17x slower
336
- ```