amq-protocol 2.4.0 → 2.5.1
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.
- checksums.yaml +4 -4
- data/ChangeLog.md +12 -5
- data/lib/amq/protocol/client.rb +30 -37
- data/lib/amq/protocol/frame.rb +2 -0
- data/lib/amq/protocol/version.rb +1 -1
- metadata +3 -52
- data/.github/ISSUE_TEMPLATE.md +0 -18
- data/.github/workflows/ci.yml +0 -31
- data/.gitignore +0 -18
- data/.gitmodules +0 -3
- data/.rspec +0 -1
- data/.travis.yml +0 -17
- data/Gemfile +0 -27
- data/Rakefile +0 -55
- data/amq-protocol.gemspec +0 -27
- data/benchmarks/frame_encoding.rb +0 -75
- data/benchmarks/int_allocator.rb +0 -34
- data/benchmarks/method_encoding.rb +0 -198
- data/benchmarks/pack_unpack.rb +0 -158
- data/benchmarks/pure/body_framing_with_256k_payload.rb +0 -28
- data/benchmarks/pure/body_framing_with_2k_payload.rb +0 -28
- data/benchmarks/run_all.rb +0 -64
- data/benchmarks/table_encoding.rb +0 -110
- data/codegen/__init__.py +0 -0
- data/codegen/amqp_0.9.1_changes.json +0 -1
- data/codegen/codegen.py +0 -151
- data/codegen/codegen_helpers.py +0 -162
- data/codegen/protocol.rb.pytemplate +0 -320
- data/generate.rb +0 -24
- data/profiling/README.md +0 -9
- data/profiling/stackprof/body_framing_with_2k_payload.rb +0 -33
- data/spec/amq/bit_set_spec.rb +0 -249
- data/spec/amq/endianness_spec.rb +0 -23
- data/spec/amq/int_allocator_spec.rb +0 -136
- data/spec/amq/pack_spec.rb +0 -58
- data/spec/amq/protocol/basic_spec.rb +0 -325
- data/spec/amq/protocol/blank_body_encoding_spec.rb +0 -9
- data/spec/amq/protocol/channel_spec.rb +0 -127
- data/spec/amq/protocol/confirm_spec.rb +0 -41
- data/spec/amq/protocol/connection_spec.rb +0 -146
- data/spec/amq/protocol/constants_spec.rb +0 -10
- data/spec/amq/protocol/exceptions_spec.rb +0 -70
- data/spec/amq/protocol/exchange_spec.rb +0 -106
- data/spec/amq/protocol/float_32bit_spec.rb +0 -27
- data/spec/amq/protocol/frame_spec.rb +0 -156
- data/spec/amq/protocol/method_spec.rb +0 -43
- data/spec/amq/protocol/queue_spec.rb +0 -126
- data/spec/amq/protocol/table_spec.rb +0 -291
- data/spec/amq/protocol/tx_spec.rb +0 -55
- data/spec/amq/protocol/value_decoder_spec.rb +0 -183
- data/spec/amq/protocol/value_encoder_spec.rb +0 -161
- data/spec/amq/protocol_spec.rb +0 -812
- data/spec/amq/settings_spec.rb +0 -58
- data/spec/amq/uri_parsing_spec.rb +0 -287
- data/spec/spec_helper.rb +0 -29
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
6
|
-
|
|
7
|
-
require "amq/protocol/client"
|
|
8
|
-
require "benchmark/ips"
|
|
9
|
-
|
|
10
|
-
puts
|
|
11
|
-
puts "-" * 80
|
|
12
|
-
puts "AMQP Method Encoding/Decoding Benchmarks on #{RUBY_DESCRIPTION}"
|
|
13
|
-
puts "-" * 80
|
|
14
|
-
|
|
15
|
-
FRAME_SIZE = 131072 # 128KB, typical default
|
|
16
|
-
|
|
17
|
-
# Common message properties
|
|
18
|
-
BASIC_PROPERTIES = {
|
|
19
|
-
content_type: "application/json",
|
|
20
|
-
delivery_mode: 2,
|
|
21
|
-
priority: 0,
|
|
22
|
-
headers: { "x-custom" => "value" }
|
|
23
|
-
}.freeze
|
|
24
|
-
|
|
25
|
-
MINIMAL_PROPERTIES = {
|
|
26
|
-
delivery_mode: 2
|
|
27
|
-
}.freeze
|
|
28
|
-
|
|
29
|
-
# Payloads
|
|
30
|
-
SMALL_BODY = '{"id":1}'.freeze
|
|
31
|
-
MEDIUM_BODY = ('x' * 1024).freeze
|
|
32
|
-
LARGE_BODY = ('x' * 65536).freeze
|
|
33
|
-
|
|
34
|
-
puts "=== Basic.Publish (Full Message Encoding) ==="
|
|
35
|
-
puts "This is the critical hot path for publishing messages"
|
|
36
|
-
puts
|
|
37
|
-
|
|
38
|
-
Benchmark.ips do |x|
|
|
39
|
-
x.config(time: 5, warmup: 2)
|
|
40
|
-
|
|
41
|
-
x.report("Publish small (8B) + minimal props") do
|
|
42
|
-
AMQ::Protocol::Basic::Publish.encode(
|
|
43
|
-
1, # channel
|
|
44
|
-
SMALL_BODY, # payload
|
|
45
|
-
MINIMAL_PROPERTIES,
|
|
46
|
-
"", # exchange
|
|
47
|
-
"test.queue", # routing_key
|
|
48
|
-
false, # mandatory
|
|
49
|
-
false, # immediate
|
|
50
|
-
FRAME_SIZE
|
|
51
|
-
)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
x.report("Publish small (8B) + full props") do
|
|
55
|
-
AMQ::Protocol::Basic::Publish.encode(
|
|
56
|
-
1,
|
|
57
|
-
SMALL_BODY,
|
|
58
|
-
BASIC_PROPERTIES,
|
|
59
|
-
"",
|
|
60
|
-
"test.queue",
|
|
61
|
-
false,
|
|
62
|
-
false,
|
|
63
|
-
FRAME_SIZE
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
x.report("Publish medium (1KB) + full props") do
|
|
68
|
-
AMQ::Protocol::Basic::Publish.encode(
|
|
69
|
-
1,
|
|
70
|
-
MEDIUM_BODY,
|
|
71
|
-
BASIC_PROPERTIES,
|
|
72
|
-
"",
|
|
73
|
-
"test.queue",
|
|
74
|
-
false,
|
|
75
|
-
false,
|
|
76
|
-
FRAME_SIZE
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
x.report("Publish large (64KB) + full props") do
|
|
81
|
-
AMQ::Protocol::Basic::Publish.encode(
|
|
82
|
-
1,
|
|
83
|
-
LARGE_BODY,
|
|
84
|
-
BASIC_PROPERTIES,
|
|
85
|
-
"",
|
|
86
|
-
"test.queue",
|
|
87
|
-
false,
|
|
88
|
-
false,
|
|
89
|
-
FRAME_SIZE
|
|
90
|
-
)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
x.compare!
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Create sample encoded methods for decoding benchmarks
|
|
97
|
-
puts
|
|
98
|
-
puts "=== Method Decoding ==="
|
|
99
|
-
|
|
100
|
-
# Simulate encoded Basic.Deliver frame payload (after class/method ID)
|
|
101
|
-
# Basic.Deliver: consumer_tag(shortstr), delivery_tag(longlong), redelivered(bit), exchange(shortstr), routing_key(shortstr)
|
|
102
|
-
def make_deliver_payload(consumer_tag, delivery_tag, exchange, routing_key)
|
|
103
|
-
buffer = String.new(encoding: 'BINARY')
|
|
104
|
-
buffer << consumer_tag.bytesize.chr
|
|
105
|
-
buffer << consumer_tag
|
|
106
|
-
buffer << AMQ::Pack.pack_uint64_big_endian(delivery_tag)
|
|
107
|
-
buffer << "\x00" # redelivered = false
|
|
108
|
-
buffer << exchange.bytesize.chr
|
|
109
|
-
buffer << exchange
|
|
110
|
-
buffer << routing_key.bytesize.chr
|
|
111
|
-
buffer << routing_key
|
|
112
|
-
buffer
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
DELIVER_PAYLOAD_SHORT = make_deliver_payload("ctag", 1, "", "q")
|
|
116
|
-
DELIVER_PAYLOAD_TYPICAL = make_deliver_payload("bunny-consumer-12345", 999999, "amq.topic", "events.user.created")
|
|
117
|
-
|
|
118
|
-
Benchmark.ips do |x|
|
|
119
|
-
x.config(time: 5, warmup: 2)
|
|
120
|
-
|
|
121
|
-
x.report("Basic.Deliver.decode (short)") do
|
|
122
|
-
AMQ::Protocol::Basic::Deliver.decode(DELIVER_PAYLOAD_SHORT)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
x.report("Basic.Deliver.decode (typical)") do
|
|
126
|
-
AMQ::Protocol::Basic::Deliver.decode(DELIVER_PAYLOAD_TYPICAL)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
x.compare!
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
puts
|
|
133
|
-
puts "=== Properties Encoding/Decoding ==="
|
|
134
|
-
|
|
135
|
-
Benchmark.ips do |x|
|
|
136
|
-
x.config(time: 5, warmup: 2)
|
|
137
|
-
|
|
138
|
-
x.report("encode_properties (minimal)") do
|
|
139
|
-
AMQ::Protocol::Basic.encode_properties(100, MINIMAL_PROPERTIES)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
x.report("encode_properties (full)") do
|
|
143
|
-
AMQ::Protocol::Basic.encode_properties(1024, BASIC_PROPERTIES)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
x.compare!
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# Create encoded properties for decode benchmark
|
|
150
|
-
ENCODED_MINIMAL_PROPS = AMQ::Protocol::Basic.encode_properties(100, MINIMAL_PROPERTIES)
|
|
151
|
-
ENCODED_FULL_PROPS = AMQ::Protocol::Basic.encode_properties(1024, BASIC_PROPERTIES)
|
|
152
|
-
|
|
153
|
-
# Skip the first 12 bytes (class_id, weight, body_size)
|
|
154
|
-
PROPS_DATA_MINIMAL = ENCODED_MINIMAL_PROPS[12..-1]
|
|
155
|
-
PROPS_DATA_FULL = ENCODED_FULL_PROPS[12..-1]
|
|
156
|
-
|
|
157
|
-
Benchmark.ips do |x|
|
|
158
|
-
x.config(time: 5, warmup: 2)
|
|
159
|
-
|
|
160
|
-
x.report("decode_properties (minimal)") do
|
|
161
|
-
AMQ::Protocol::Basic.decode_properties(PROPS_DATA_MINIMAL)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
x.report("decode_properties (full)") do
|
|
165
|
-
AMQ::Protocol::Basic.decode_properties(PROPS_DATA_FULL)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
x.compare!
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
puts
|
|
172
|
-
puts "=== Other Common Methods ==="
|
|
173
|
-
|
|
174
|
-
Benchmark.ips do |x|
|
|
175
|
-
x.config(time: 5, warmup: 2)
|
|
176
|
-
|
|
177
|
-
x.report("Basic.Ack.encode") do
|
|
178
|
-
AMQ::Protocol::Basic::Ack.encode(1, 12345, false)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
x.report("Basic.Nack.encode") do
|
|
182
|
-
AMQ::Protocol::Basic::Nack.encode(1, 12345, false, true)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
x.report("Basic.Reject.encode") do
|
|
186
|
-
AMQ::Protocol::Basic::Reject.encode(1, 12345, true)
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
x.report("Queue.Declare.encode") do
|
|
190
|
-
AMQ::Protocol::Queue::Declare.encode(1, "test.queue", false, true, false, false, false, {})
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
x.report("Exchange.Declare.encode") do
|
|
194
|
-
AMQ::Protocol::Exchange::Declare.encode(1, "test.exchange", "topic", false, true, false, false, false, {})
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
x.compare!
|
|
198
|
-
end
|
data/benchmarks/pack_unpack.rb
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
6
|
-
|
|
7
|
-
require "amq/protocol/client"
|
|
8
|
-
require "benchmark/ips"
|
|
9
|
-
|
|
10
|
-
puts
|
|
11
|
-
puts "-" * 80
|
|
12
|
-
puts "Pack/Unpack Micro-benchmarks on #{RUBY_DESCRIPTION}"
|
|
13
|
-
puts "-" * 80
|
|
14
|
-
|
|
15
|
-
# Test data
|
|
16
|
-
UINT64_VALUE = 0x123456789ABCDEF0
|
|
17
|
-
UINT32_VALUE = 0x12345678
|
|
18
|
-
UINT16_VALUE = 0x1234
|
|
19
|
-
|
|
20
|
-
PACKED_UINT64_BE = (+"\x12\x34\x56\x78\x9A\xBC\xDE\xF0").force_encoding('BINARY').freeze
|
|
21
|
-
PACKED_UINT32_BE = (+"\x12\x34\x56\x78").force_encoding('BINARY').freeze
|
|
22
|
-
PACKED_UINT16_BE = (+"\x12\x34").force_encoding('BINARY').freeze
|
|
23
|
-
|
|
24
|
-
puts "=== Pack Operations ==="
|
|
25
|
-
|
|
26
|
-
Benchmark.ips do |x|
|
|
27
|
-
x.config(time: 5, warmup: 2)
|
|
28
|
-
|
|
29
|
-
x.report("AMQ::Pack.pack_uint64_big_endian") do
|
|
30
|
-
AMQ::Pack.pack_uint64_big_endian(UINT64_VALUE)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Alternative: direct pack with 'Q>' directive (Ruby 1.9.3+)
|
|
34
|
-
x.report("[val].pack('Q>')") do
|
|
35
|
-
[UINT64_VALUE].pack('Q>')
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
x.report("[val].pack('N') uint32") do
|
|
39
|
-
[UINT32_VALUE].pack('N')
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
x.report("[val].pack('n') uint16") do
|
|
43
|
-
[UINT16_VALUE].pack('n')
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
x.compare!
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
puts
|
|
50
|
-
puts "=== Unpack Operations ==="
|
|
51
|
-
|
|
52
|
-
Benchmark.ips do |x|
|
|
53
|
-
x.config(time: 5, warmup: 2)
|
|
54
|
-
|
|
55
|
-
x.report("AMQ::Pack.unpack_uint64_big_endian") do
|
|
56
|
-
AMQ::Pack.unpack_uint64_big_endian(PACKED_UINT64_BE)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Alternative: direct unpack with 'Q>' directive
|
|
60
|
-
x.report("data.unpack('Q>')") do
|
|
61
|
-
PACKED_UINT64_BE.unpack('Q>')
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
x.report("data.unpack1('Q>')") do
|
|
65
|
-
PACKED_UINT64_BE.unpack1('Q>')
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
x.report("data.unpack('N').first") do
|
|
69
|
-
PACKED_UINT32_BE.unpack('N').first
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
x.report("data.unpack1('N')") do
|
|
73
|
-
PACKED_UINT32_BE.unpack1('N')
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
x.compare!
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
puts
|
|
80
|
-
puts "=== String Slicing ==="
|
|
81
|
-
|
|
82
|
-
DATA = ("x" * 1000).force_encoding('BINARY').freeze
|
|
83
|
-
|
|
84
|
-
Benchmark.ips do |x|
|
|
85
|
-
x.config(time: 5, warmup: 2)
|
|
86
|
-
|
|
87
|
-
x.report("data[offset, length]") do
|
|
88
|
-
DATA[100, 50]
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
x.report("data.byteslice(offset, length)") do
|
|
92
|
-
DATA.byteslice(100, 50)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
x.report("data.slice(offset, length)") do
|
|
96
|
-
DATA.slice(100, 50)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
x.compare!
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
puts
|
|
103
|
-
puts "=== Single Byte Access ==="
|
|
104
|
-
|
|
105
|
-
Benchmark.ips do |x|
|
|
106
|
-
x.config(time: 5, warmup: 2)
|
|
107
|
-
|
|
108
|
-
x.report("data[0, 1].unpack('C').first") do
|
|
109
|
-
DATA[0, 1].unpack('C').first
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
x.report("data.getbyte(0)") do
|
|
113
|
-
DATA.getbyte(0)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
x.report("data[0].ord") do
|
|
117
|
-
DATA[0].ord
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
x.report("data.unpack1('C')") do
|
|
121
|
-
DATA.unpack1('C')
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
x.compare!
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
puts
|
|
128
|
-
puts "=== Buffer Building ==="
|
|
129
|
-
|
|
130
|
-
Benchmark.ips do |x|
|
|
131
|
-
x.config(time: 5, warmup: 2)
|
|
132
|
-
|
|
133
|
-
x.report("String.new + <<") do
|
|
134
|
-
buf = String.new
|
|
135
|
-
buf << "hello"
|
|
136
|
-
buf << "world"
|
|
137
|
-
buf << [1234].pack('N')
|
|
138
|
-
buf
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
x.report("+'' + <<") do
|
|
142
|
-
buf = +''
|
|
143
|
-
buf << "hello"
|
|
144
|
-
buf << "world"
|
|
145
|
-
buf << [1234].pack('N')
|
|
146
|
-
buf
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
x.report("Array#join") do
|
|
150
|
-
parts = []
|
|
151
|
-
parts << "hello"
|
|
152
|
-
parts << "world"
|
|
153
|
-
parts << [1234].pack('N')
|
|
154
|
-
parts.join
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
x.compare!
|
|
158
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
|
|
4
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
|
|
5
|
-
|
|
6
|
-
require "amq/protocol/client"
|
|
7
|
-
require "benchmark"
|
|
8
|
-
|
|
9
|
-
FRAME_SIZE = 128 * 1024
|
|
10
|
-
|
|
11
|
-
puts
|
|
12
|
-
puts "-" * 80
|
|
13
|
-
puts "Benchmarking on #{RUBY_DESCRIPTION}"
|
|
14
|
-
|
|
15
|
-
n = 250_000
|
|
16
|
-
|
|
17
|
-
# warm up the JIT, etc
|
|
18
|
-
puts "Doing a warmup run..."
|
|
19
|
-
15_000.times { AMQ::Protocol::Method.encode_body("a" * 256 * 1024, 1, FRAME_SIZE) }
|
|
20
|
-
|
|
21
|
-
t = Benchmark.realtime do
|
|
22
|
-
n.times { AMQ::Protocol::Method.encode_body("a" * 256 * 1024, 1, FRAME_SIZE) }
|
|
23
|
-
end
|
|
24
|
-
r = (n.to_f/t.to_f)
|
|
25
|
-
|
|
26
|
-
puts "AMQ::Protocol::Method.encode_body rate: #{(r / 1000).round(2)} KGHz"
|
|
27
|
-
puts
|
|
28
|
-
puts "-" * 80
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
|
|
4
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib"))
|
|
5
|
-
|
|
6
|
-
require "amq/protocol/client"
|
|
7
|
-
require "benchmark"
|
|
8
|
-
|
|
9
|
-
FRAME_SIZE = 128 * 1024
|
|
10
|
-
|
|
11
|
-
puts
|
|
12
|
-
puts "-" * 80
|
|
13
|
-
puts "Benchmarking on #{RUBY_DESCRIPTION}"
|
|
14
|
-
|
|
15
|
-
n = 250_000
|
|
16
|
-
|
|
17
|
-
# warm up the JIT, etc
|
|
18
|
-
puts "Doing a warmup run..."
|
|
19
|
-
15_000.times { AMQ::Protocol::Method.encode_body("ab" * 1024, 1, FRAME_SIZE) }
|
|
20
|
-
|
|
21
|
-
t = Benchmark.realtime do
|
|
22
|
-
n.times { AMQ::Protocol::Method.encode_body("ab" * 1024, 1, FRAME_SIZE) }
|
|
23
|
-
end
|
|
24
|
-
r = (n.to_f/t.to_f)
|
|
25
|
-
|
|
26
|
-
puts "AMQ::Protocol::Method.encode_body rate: #{(r / 1000).round(2)} KGHz"
|
|
27
|
-
puts
|
|
28
|
-
puts "-" * 80
|
data/benchmarks/run_all.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
# Master benchmark runner
|
|
6
|
-
# Usage: ruby benchmarks/run_all.rb
|
|
7
|
-
|
|
8
|
-
require 'fileutils'
|
|
9
|
-
|
|
10
|
-
BENCHMARK_DIR = File.dirname(__FILE__)
|
|
11
|
-
RESULTS_DIR = File.join(BENCHMARK_DIR, "results")
|
|
12
|
-
|
|
13
|
-
FileUtils.mkdir_p(RESULTS_DIR)
|
|
14
|
-
|
|
15
|
-
benchmarks = %w[
|
|
16
|
-
pack_unpack.rb
|
|
17
|
-
frame_encoding.rb
|
|
18
|
-
table_encoding.rb
|
|
19
|
-
method_encoding.rb
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
|
|
23
|
-
ruby_version = RUBY_VERSION.gsub('.', '_')
|
|
24
|
-
results_file = File.join(RESULTS_DIR, "benchmark_#{ruby_version}_#{timestamp}.txt")
|
|
25
|
-
|
|
26
|
-
puts "=" * 80
|
|
27
|
-
puts "AMQ-Protocol Benchmark Suite"
|
|
28
|
-
puts "=" * 80
|
|
29
|
-
puts "Ruby: #{RUBY_DESCRIPTION}"
|
|
30
|
-
puts "Time: #{Time.now}"
|
|
31
|
-
puts "Results will be saved to: #{results_file}"
|
|
32
|
-
puts "=" * 80
|
|
33
|
-
puts
|
|
34
|
-
|
|
35
|
-
File.open(results_file, 'w') do |f|
|
|
36
|
-
f.puts "AMQ-Protocol Benchmark Results"
|
|
37
|
-
f.puts "Ruby: #{RUBY_DESCRIPTION}"
|
|
38
|
-
f.puts "Time: #{Time.now}"
|
|
39
|
-
f.puts "=" * 80
|
|
40
|
-
f.puts
|
|
41
|
-
|
|
42
|
-
benchmarks.each do |benchmark|
|
|
43
|
-
benchmark_path = File.join(BENCHMARK_DIR, benchmark)
|
|
44
|
-
|
|
45
|
-
if File.exist?(benchmark_path)
|
|
46
|
-
puts "\n>>> Running #{benchmark}..."
|
|
47
|
-
puts
|
|
48
|
-
|
|
49
|
-
output = `ruby #{benchmark_path} 2>&1`
|
|
50
|
-
puts output
|
|
51
|
-
|
|
52
|
-
f.puts ">>> #{benchmark}"
|
|
53
|
-
f.puts output
|
|
54
|
-
f.puts
|
|
55
|
-
else
|
|
56
|
-
puts "Warning: #{benchmark_path} not found, skipping..."
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
puts
|
|
62
|
-
puts "=" * 80
|
|
63
|
-
puts "Benchmark complete! Results saved to: #{results_file}"
|
|
64
|
-
puts "=" * 80
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# encoding: utf-8
|
|
3
|
-
# frozen_string_literal: true
|
|
4
|
-
|
|
5
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
6
|
-
|
|
7
|
-
require "amq/protocol/client"
|
|
8
|
-
require "benchmark/ips"
|
|
9
|
-
|
|
10
|
-
puts
|
|
11
|
-
puts "-" * 80
|
|
12
|
-
puts "Table Encoding/Decoding Benchmarks on #{RUBY_DESCRIPTION}"
|
|
13
|
-
puts "-" * 80
|
|
14
|
-
|
|
15
|
-
# Test data - various table sizes and types
|
|
16
|
-
EMPTY_TABLE = {}
|
|
17
|
-
|
|
18
|
-
SIMPLE_TABLE = {
|
|
19
|
-
"key1" => "value1",
|
|
20
|
-
"key2" => 42,
|
|
21
|
-
"key3" => true
|
|
22
|
-
}.freeze
|
|
23
|
-
|
|
24
|
-
TYPICAL_HEADERS = {
|
|
25
|
-
"content_type" => "application/json",
|
|
26
|
-
"content_encoding" => "utf-8",
|
|
27
|
-
"x-custom-header" => "some-value",
|
|
28
|
-
"x-retry-count" => 3,
|
|
29
|
-
"x-timestamp" => Time.now.to_i
|
|
30
|
-
}.freeze
|
|
31
|
-
|
|
32
|
-
COMPLEX_TABLE = {
|
|
33
|
-
"string" => "hello world",
|
|
34
|
-
"integer" => 123456789,
|
|
35
|
-
"float" => 3.14159,
|
|
36
|
-
"boolean_true" => true,
|
|
37
|
-
"boolean_false" => false,
|
|
38
|
-
"nested" => {
|
|
39
|
-
"inner_key" => "inner_value",
|
|
40
|
-
"inner_number" => 999
|
|
41
|
-
},
|
|
42
|
-
"array" => [1, 2, 3, "four", true]
|
|
43
|
-
}.freeze
|
|
44
|
-
|
|
45
|
-
LARGE_TABLE = (1..50).to_h { |i| ["key_#{i}", "value_#{i}"] }.freeze
|
|
46
|
-
|
|
47
|
-
# Pre-encode tables for decode benchmarks
|
|
48
|
-
ENCODED_EMPTY = AMQ::Protocol::Table.encode(EMPTY_TABLE)
|
|
49
|
-
ENCODED_SIMPLE = AMQ::Protocol::Table.encode(SIMPLE_TABLE)
|
|
50
|
-
ENCODED_TYPICAL = AMQ::Protocol::Table.encode(TYPICAL_HEADERS)
|
|
51
|
-
ENCODED_COMPLEX = AMQ::Protocol::Table.encode(COMPLEX_TABLE)
|
|
52
|
-
ENCODED_LARGE = AMQ::Protocol::Table.encode(LARGE_TABLE)
|
|
53
|
-
|
|
54
|
-
puts "Table sizes (bytes): empty=#{ENCODED_EMPTY.bytesize}, simple=#{ENCODED_SIMPLE.bytesize}, typical=#{ENCODED_TYPICAL.bytesize}, complex=#{ENCODED_COMPLEX.bytesize}, large=#{ENCODED_LARGE.bytesize}"
|
|
55
|
-
puts
|
|
56
|
-
|
|
57
|
-
puts "=== Table Encoding ==="
|
|
58
|
-
Benchmark.ips do |x|
|
|
59
|
-
x.config(time: 5, warmup: 2)
|
|
60
|
-
|
|
61
|
-
x.report("encode empty") do
|
|
62
|
-
AMQ::Protocol::Table.encode(EMPTY_TABLE)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
x.report("encode simple (3 keys)") do
|
|
66
|
-
AMQ::Protocol::Table.encode(SIMPLE_TABLE)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
x.report("encode typical headers (5 keys)") do
|
|
70
|
-
AMQ::Protocol::Table.encode(TYPICAL_HEADERS)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
x.report("encode complex (nested/array)") do
|
|
74
|
-
AMQ::Protocol::Table.encode(COMPLEX_TABLE)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
x.report("encode large (50 keys)") do
|
|
78
|
-
AMQ::Protocol::Table.encode(LARGE_TABLE)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
x.compare!
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
puts
|
|
85
|
-
puts "=== Table Decoding ==="
|
|
86
|
-
Benchmark.ips do |x|
|
|
87
|
-
x.config(time: 5, warmup: 2)
|
|
88
|
-
|
|
89
|
-
x.report("decode empty") do
|
|
90
|
-
AMQ::Protocol::Table.decode(ENCODED_EMPTY)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
x.report("decode simple (3 keys)") do
|
|
94
|
-
AMQ::Protocol::Table.decode(ENCODED_SIMPLE)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
x.report("decode typical headers (5 keys)") do
|
|
98
|
-
AMQ::Protocol::Table.decode(ENCODED_TYPICAL)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
x.report("decode complex (nested/array)") do
|
|
102
|
-
AMQ::Protocol::Table.decode(ENCODED_COMPLEX)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
x.report("decode large (50 keys)") do
|
|
106
|
-
AMQ::Protocol::Table.decode(ENCODED_LARGE)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
x.compare!
|
|
110
|
-
end
|
data/codegen/__init__.py
DELETED
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"tx": {"select-ok": ["client"], "rollback": ["server"], "commit": ["server"], "rollback-ok": ["client"], "select": ["server"], "commit-ok": ["client"]}, "exchange": {"delete-ok": ["client"], "declare-ok": ["client"], "declare": ["server"], "delete": ["server"], "bind": ["server"], "bind-ok": ["client"], "unbind": ["server"], "unbind-ok": ["client"]}, "queue": {"unbind": ["server"], "unbind-ok": ["client"], "purge-ok": ["client"], "bind": ["server"], "purge": ["server"], "declare-ok": ["client"], "delete-ok": ["client"], "delete": ["server"], "declare": ["server"], "bind-ok": ["client"]}, "connection": {"secure": ["client"], "secure-ok": ["server"], "open-ok": ["client"], "close-ok": ["client", "server"], "start": ["client"], "tune": ["client"], "start-ok": ["server"], "close": ["client", "server"], "open": ["server"], "tune-ok": ["server"]}, "basic": {"qos": ["server"], "consume": ["server"], "reject": ["server"], "get": ["server"], "ack": ["client", "server"], "get-ok": ["client"], "consume-ok": ["client"], "deliver": ["client"], "recover-ok": ["client"], "publish": ["server"], "cancel": ["server", "client"], "recover-async": ["server"], "get-empty": ["client"], "qos-ok": ["client"], "return": ["client"], "recover": ["server"], "cancel-ok": ["client"]}, "channel": {"flow-ok": ["server", "client"], "flow": ["server", "client"], "open-ok": ["client"], "close-ok": ["client", "server"], "close": ["client", "server"], "open": ["server"]}}
|