Skip to content

Commit 6b04523

Browse files
committed
chore: add benchmark and profiling scripts
1 parent a58a125 commit 6b04523

File tree

8 files changed

+351
-0
lines changed

8 files changed

+351
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99

1010
# rspec failure tracking
1111
.rspec_status
12+
13+
# profile results folder
14+
/profile/
15+
!/profile/.keep

Gemfile.lock

+38
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,39 @@ GEM
77
remote: https://rubygems.org/
88
specs:
99
ast (2.4.0)
10+
benchmark-ips (2.7.2)
1011
codecov (0.1.14)
1112
json
1213
simplecov
1314
url
1415
coderay (1.1.2)
16+
concurrent-ruby (1.1.5)
1517
diff-lcs (1.3)
1618
docile (1.3.1)
19+
dry-configurable (0.8.3)
20+
concurrent-ruby (~> 1.0)
21+
dry-core (~> 0.4, >= 0.4.7)
22+
dry-container (0.7.2)
23+
concurrent-ruby (~> 1.0)
24+
dry-configurable (~> 0.1, >= 0.1.3)
25+
dry-core (0.4.9)
26+
concurrent-ruby (~> 1.0)
27+
dry-equalizer (0.2.2)
28+
dry-events (0.2.0)
29+
concurrent-ruby (~> 1.0)
30+
dry-core (~> 0.4)
31+
dry-equalizer (~> 0.2)
32+
dry-matcher (0.8.1)
33+
dry-core (>= 0.4.7)
34+
dry-monads (1.3.0)
35+
concurrent-ruby (~> 1.0)
36+
dry-core (~> 0.4, >= 0.4.4)
37+
dry-equalizer
38+
dry-transaction (0.13.0)
39+
dry-container (>= 0.2.8)
40+
dry-events (>= 0.1.0)
41+
dry-matcher (>= 0.7.0)
42+
dry-monads (>= 0.4.0)
1743
jaro_winkler (1.5.2)
1844
json (2.2.0)
1945
method_source (0.9.2)
@@ -51,29 +77,41 @@ GEM
5177
rubocop (>= 0.58.0)
5278
rubocop-rspec (1.32.0)
5379
rubocop (>= 0.60.0)
80+
ruby-prof (1.0.0)
5481
ruby-progressbar (1.10.0)
5582
simplecov (0.16.1)
5683
docile (~> 1.1)
5784
json (>= 1.8, < 3)
5885
simplecov-html (~> 0.10.0)
5986
simplecov-html (0.10.2)
87+
trailblazer-activity (0.8.4)
88+
trailblazer-context (>= 0.1.4)
89+
trailblazer-activity-dsl-linear (0.1.8)
90+
trailblazer-activity (>= 0.8.3, < 1.0.0)
91+
trailblazer-context (0.1.4)
92+
trailblazer-operation (0.5.2)
93+
trailblazer-activity-dsl-linear (>= 0.1.6, < 1.0.0)
6094
unicode-display_width (1.5.0)
6195
url (0.3.2)
6296

6397
PLATFORMS
6498
ruby
6599

66100
DEPENDENCIES
101+
benchmark-ips
67102
bundler (~> 2.0)
68103
codecov
104+
dry-transaction
69105
flows!
70106
pry
71107
rake (~> 10.0)
72108
rspec (~> 3.0)
73109
rubocop
74110
rubocop-performance
75111
rubocop-rspec
112+
ruby-prof
76113
simplecov
114+
trailblazer-operation
77115

78116
BUNDLED WITH
79117
2.0.1

bin/benchmark

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env ruby
2+
# rubocop:disable all
3+
4+
require 'bundler/setup'
5+
require 'benchmark/ips'
6+
7+
require_relative './examples'
8+
9+
puts '-' * 50
10+
puts '- task: A + B, one step implementation'
11+
puts '-' * 50
12+
13+
flows_summator = FlowsSummator.new
14+
dry_summator = DrySummator.new
15+
16+
Benchmark.ips do |b|
17+
b.report 'Flows::Operation (build each time)' do
18+
FlowsSummator.new.call(a: 1, b: 2)
19+
end
20+
21+
b.report 'Flows::Operation (build once)' do
22+
flows_summator.call(a: 1, b: 2)
23+
end
24+
25+
unless ENV['FLOWS_ONLY']
26+
b.report 'Dry::Transaction (build each time)' do
27+
DrySummator.new.call(a: 1, b: 2)
28+
end
29+
30+
b.report 'Dry::Transaction (build once)' do
31+
dry_summator.call(a: 1, b: 2)
32+
end
33+
34+
b.report 'Trailblazer::Operation' do
35+
TBSummator.call(a: 1, b: 2)
36+
end
37+
end
38+
39+
if ENV['WITH_PORO']
40+
b.report 'PORO' do
41+
POROSummator.call(a: 1, b: 2)
42+
end
43+
end
44+
45+
b.compare!
46+
end unless ENV['SKIP_SUM']
47+
puts
48+
49+
50+
puts '-' * 50
51+
puts '- task: ten steps returns successful result'
52+
puts '-' * 50
53+
54+
flows_ten_steps = FlowsTenSteps.new
55+
dry_ten_steps = DryTenSteps.new
56+
57+
Benchmark.ips do |b|
58+
b.report 'Flows::Operation (build each time)' do
59+
FlowsTenSteps.new.call(a: 1, b: 2)
60+
end
61+
62+
b.report 'Flows::Operation (build once)' do
63+
flows_ten_steps.call(a: 1, b: 2)
64+
end
65+
66+
unless ENV['FLOWS_ONLY']
67+
b.report 'Dry::Transaction (build each time)' do
68+
DryTenSteps.new.call(a: 1, b: 2)
69+
end
70+
71+
b.report 'Dry::Transaction (build once)' do
72+
dry_ten_steps.call(a: 1, b: 2)
73+
end
74+
75+
b.report 'Trailblazer::Operation' do
76+
TBTenSteps.call(a: 1, b: 2)
77+
end
78+
end
79+
80+
if ENV['WITH_PORO']
81+
b.report 'PORO' do
82+
POROTenSteps.call
83+
end
84+
end
85+
86+
b.compare!
87+
end unless ENV['SKIP_10']
88+
puts

bin/examples.rb

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
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+
success :sum
16+
17+
def sum(a:, b:, **)
18+
ok(sum: a + b)
19+
end
20+
end
21+
22+
class POROSummator
23+
def self.call(a:, b:)
24+
a + b
25+
end
26+
end
27+
28+
class DrySummator
29+
include Dry::Transaction
30+
31+
step :sum
32+
33+
private
34+
35+
def sum(a:, b:)
36+
Success(a + b)
37+
end
38+
end
39+
40+
class TBSummator < Trailblazer::Operation
41+
step :sum
42+
43+
def sum(opts, a:, b:, **)
44+
opts[:sum] = a + b
45+
end
46+
end
47+
48+
#
49+
# Task: 10 steps which returs simple value
50+
#
51+
52+
class FlowsTenSteps
53+
include Flows::Operation
54+
55+
step :s1
56+
step :s2
57+
step :s3
58+
step :s4
59+
step :s5
60+
step :s6
61+
step :s7
62+
step :s8
63+
step :s9
64+
step :s10
65+
66+
success :data
67+
68+
def s1(**); ok(s1: true); end
69+
def s2(**); ok(s2: true); end
70+
def s3(**); ok(s3: true); end
71+
def s4(**); ok(s4: true); end
72+
def s5(**); ok(s5: true); end
73+
def s5(**); ok(s5: true); end
74+
def s6(**); ok(s6: true); end
75+
def s7(**); ok(s7: true); end
76+
def s8(**); ok(s8: true); end
77+
def s9(**); ok(s9: true); end
78+
def s10(**); ok(data: :ok); end
79+
end
80+
81+
class POROTenSteps
82+
class << self
83+
def call()
84+
s1
85+
s2
86+
s3
87+
s4
88+
s5
89+
s6
90+
s7
91+
s8
92+
s9
93+
s10
94+
end
95+
96+
def s1; true; end
97+
def s2; true; end
98+
def s3; true; end
99+
def s4; true; end
100+
def s5; true; end
101+
def s6; true; end
102+
def s7; true; end
103+
def s8; true; end
104+
def s9; true; end
105+
def s10; true; end
106+
end
107+
end
108+
109+
class DryTenSteps
110+
include Dry::Transaction
111+
112+
step :s1
113+
step :s2
114+
step :s3
115+
step :s4
116+
step :s5
117+
step :s6
118+
step :s7
119+
step :s8
120+
step :s9
121+
step :s10
122+
123+
private
124+
125+
def s1; Success(true); end
126+
def s2; Success(true); end
127+
def s3; Success(true); end
128+
def s4; Success(true); end
129+
def s5; Success(true); end
130+
def s6; Success(true); end
131+
def s7; Success(true); end
132+
def s8; Success(true); end
133+
def s9; Success(true); end
134+
def s10; Success(true); end
135+
end
136+
137+
class TBTenSteps < Trailblazer::Operation
138+
step :s1
139+
step :s2
140+
step :s3
141+
step :s4
142+
step :s5
143+
step :s6
144+
step :s7
145+
step :s8
146+
step :s9
147+
step :s10
148+
149+
def s1(opts, **); opts[:s1] = true; end
150+
def s2(opts, **); opts[:s2] = true; end
151+
def s3(opts, **); opts[:s3] = true; end
152+
def s4(opts, **); opts[:s4] = true; end
153+
def s5(opts, **); opts[:s5] = true; end
154+
def s6(opts, **); opts[:s6] = true; end
155+
def s7(opts, **); opts[:s7] = true; end
156+
def s8(opts, **); opts[:s8] = true; end
157+
def s9(opts, **); opts[:s9] = true; end
158+
def s10(opts, **); opts[:s10] = true; end
159+
end

bin/profile_10steps

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env ruby
2+
# rubocop:disable all
3+
4+
require 'bundler/setup'
5+
require 'ruby-prof'
6+
7+
require_relative './examples'
8+
9+
puts 'Profile building...'
10+
result = RubyProf.profile do
11+
10_000.times do
12+
FlowsTenSteps.new
13+
end
14+
end
15+
printer = RubyProf::MultiPrinter.new(result)
16+
printer.print(path: 'profile', profile: '10steps_build_10k_times')
17+
18+
19+
flows_ten_steps = FlowsTenSteps.new
20+
21+
puts 'Profile execution...'
22+
result = RubyProf.profile do
23+
10_000.times {
24+
flows_ten_steps.call
25+
}
26+
end
27+
printer = RubyProf::MultiPrinter.new(result)
28+
printer.print(path: 'profile', profile: '10steps_execution_10k_times')

bin/ruby_benchmarks

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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

0 commit comments

Comments
 (0)