Skip to content

Commit 7f9a622

Browse files
committed
chore: add rpc schema benchmarks
1 parent fc299b8 commit 7f9a622

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ gemspec
33

44
gem "pry-byebug", platform: :mri
55

6+
gem "benchmark_driver"
7+
68
local_gemfile = "#{File.dirname(__FILE__)}/Gemfile.local"
79

810
if File.exist?(local_gemfile)

benchmarks/ruby/request_env_bench.rb

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# frozen_string_literal: true
2+
3+
require "benchmark_driver"
4+
5+
# This is the benchmark to measure the impact of promoting some HTTP headers
6+
# to Env fields. That should reduce the payload size as well as improve the rack env building
7+
# speed.
8+
9+
protobuf = <<~CODE
10+
require "google/protobuf"
11+
12+
Google::Protobuf::DescriptorPool.generated_pool.build do
13+
add_file("rpc-bench.proto", syntax: :proto3) do
14+
add_message "anycable_bench.Env" do
15+
optional :path, :string, 1
16+
map :headers, :string, :string, 2
17+
end
18+
end
19+
20+
add_file("rpc-bench.proto", syntax: :proto3) do
21+
add_message "anycable_bench.FlatEnv" do
22+
optional :path, :string, 1
23+
optional :query, :string, 2
24+
optional :host, :string, 3
25+
optional :port, :string, 4
26+
optional :scheme, :string, 5
27+
optional :cookie, :string, 6
28+
optional :origin, :string, 7
29+
optional :remote_addr, :string, 8
30+
map :headers, :string, :string, 9
31+
end
32+
end
33+
end
34+
35+
Env = Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable_bench.Env").msgclass
36+
FlatEnv = Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable_bench.FlatEnv").msgclass
37+
38+
message = Env.new(
39+
path: "/cable?token=secret",
40+
headers: {
41+
"cookie" => "session_id=123456;",
42+
"remote_addr" => "192.1.1.42",
43+
"origin" => "anycable.io",
44+
"x-api-token" => "api-token-2020"
45+
}
46+
)
47+
48+
payload = Env.encode(message)
49+
50+
message2 = FlatEnv.new(
51+
path: "/cable",
52+
query: "?token=secret",
53+
port: "80",
54+
scheme: "ws://",
55+
host: "ws.anycable.io",
56+
cookie: "session_id=123456;",
57+
origin: "anycable.io",
58+
remote_addr: "192.1.1.42",
59+
headers: {
60+
"x-api-token" => "api-token-2020"
61+
}
62+
)
63+
64+
payload2 = FlatEnv.encode(message2)
65+
66+
def build_rack(rpc_env)
67+
uri = URI.parse(rpc_env.path)
68+
69+
env = {}
70+
env.merge!(
71+
"PATH_INFO" => uri.path,
72+
"QUERY_STRING" => uri.query,
73+
"SERVER_NAME" => uri.host,
74+
"SERVER_PORT" => uri.port.to_s,
75+
"HTTP_HOST" => uri.host,
76+
"REMOTE_ADDR" => rpc_env.headers.delete("remote_addr"),
77+
"rack.url_scheme" => uri.scheme
78+
)
79+
80+
env.merge!(build_headers(rpc_env.headers))
81+
end
82+
83+
def build_rack2(rpc_env)
84+
env = {}
85+
env.merge!(
86+
"PATH_INFO" => rpc_env.path,
87+
"QUERY_STRING" => rpc_env.query,
88+
"SERVER_NAME" => rpc_env.host,
89+
"SERVER_PORT" => rpc_env.port,
90+
"HTTP_HOST" => rpc_env.host,
91+
"REMOTE_ADDR" => rpc_env.remote_addr,
92+
"rack.url_scheme" => rpc_env.scheme
93+
)
94+
95+
env.merge!(build_headers(rpc_env.headers))
96+
end
97+
98+
def build_headers(headers)
99+
headers.each_with_object({}) do |(k, v), obj|
100+
k = k.upcase
101+
k.tr!("-", "_")
102+
obj["HTTP_\#{k}"] = v
103+
end
104+
end
105+
CODE
106+
107+
Benchmark.driver do |x|
108+
x.prelude %(
109+
#{protobuf}
110+
)
111+
112+
x.report "#decode (baseline)", %{
113+
Env.decode(payload)
114+
}
115+
116+
x.report "#decode (flatten)", %{
117+
FlatEnv.decode(payload2)
118+
}
119+
end
120+
121+
Benchmark.driver do |x|
122+
x.prelude %(
123+
#{protobuf}
124+
)
125+
126+
x.report "#build_rack (baseline)", %(
127+
build_rack message
128+
)
129+
130+
x.report "#build_rack (flatten)", %(
131+
build_rack2 message2
132+
)
133+
end
134+
135+
Benchmark.driver do |x|
136+
x.prelude %(
137+
#{protobuf}
138+
)
139+
140+
x.report "#decode + #build_rack (baseline)", %{
141+
build_rack Env.decode(payload)
142+
}
143+
144+
x.report "#decode + #build_rack (flatten)", %{
145+
build_rack2 FlatEnv.decode(payload2)
146+
}
147+
end

0 commit comments

Comments
 (0)