1 use criterion::{black_box, criterion_group, criterion_main, Criterion};
2
call() -> impl IntoIterator<Item = &'static str>3 fn call() -> impl IntoIterator<Item = &'static str> {
4 [
5 "/user/repos",
6 "/repos/rust-lang/rust/stargazers",
7 "/orgs/rust-lang/public_members/nikomatsakis",
8 "/repos/rust-lang/rust/releases/1.51.0",
9 ]
10 }
11
compare_routers(c: &mut Criterion)12 fn compare_routers(c: &mut Criterion) {
13 let mut group = c.benchmark_group("Compare Routers");
14
15 let mut matchit = matchit::Router::new();
16 for route in register!(colon) {
17 matchit.insert(route, true).unwrap();
18 }
19 group.bench_function("matchit", |b| {
20 b.iter(|| {
21 for route in black_box(call()) {
22 black_box(matchit.at(route).unwrap());
23 }
24 });
25 });
26
27 let mut path_tree = path_tree::PathTree::new();
28 for route in register!(colon) {
29 path_tree.insert(route, true);
30 }
31 group.bench_function("path-tree", |b| {
32 b.iter(|| {
33 for route in black_box(call()) {
34 black_box(path_tree.find(route).unwrap());
35 }
36 });
37 });
38
39 let gonzales = gonzales::RouterBuilder::new().build(register!(brackets));
40 group.bench_function("gonzales", |b| {
41 b.iter(|| {
42 for route in black_box(call()) {
43 black_box(gonzales.route(route).unwrap());
44 }
45 });
46 });
47
48 let mut actix = actix_router::Router::<bool>::build();
49 for route in register!(brackets) {
50 actix.path(route, true);
51 }
52 let actix = actix.finish();
53 group.bench_function("actix", |b| {
54 b.iter(|| {
55 for route in black_box(call()) {
56 let mut path = actix_router::Path::new(route);
57 black_box(actix.recognize(&mut path).unwrap());
58 }
59 });
60 });
61
62 let regex_set = regex::RegexSet::new(register!(regex)).unwrap();
63 group.bench_function("regex", |b| {
64 b.iter(|| {
65 for route in black_box(call()) {
66 black_box(regex_set.matches(route));
67 }
68 });
69 });
70
71 let mut route_recognizer = route_recognizer::Router::new();
72 for route in register!(colon) {
73 route_recognizer.add(route, true);
74 }
75 group.bench_function("route-recognizer", |b| {
76 b.iter(|| {
77 for route in black_box(call()) {
78 black_box(route_recognizer.recognize(route).unwrap());
79 }
80 });
81 });
82
83 let mut routefinder = routefinder::Router::new();
84 for route in register!(colon) {
85 routefinder.add(route, true).unwrap();
86 }
87 group.bench_function("routefinder", |b| {
88 b.iter(|| {
89 for route in black_box(call()) {
90 black_box(routefinder.best_match(route).unwrap());
91 }
92 });
93 });
94
95 group.finish();
96 }
97
98 criterion_group!(benches, compare_routers);
99 criterion_main!(benches);
100
101 macro_rules! register {
102 (colon) => {{
103 register!(finish => ":p1", ":p2", ":p3", ":p4")
104 }};
105 (brackets) => {{
106 register!(finish => "{p1}", "{p2}", "{p3}", "{p4}")
107 }};
108 (regex) => {{
109 register!(finish => "(.*)", "(.*)", "(.*)", "(.*)")
110 }};
111 (finish => $p1:literal, $p2:literal, $p3:literal, $p4:literal) => {{
112 [
113 concat!("/authorizations"),
114 concat!("/authorizations/", $p1),
115 concat!("/applications/", $p1, "/tokens/", $p2),
116 concat!("/events"),
117 concat!("/repos/", $p1, "/", $p2, "/events"),
118 concat!("/networks/", $p1, "/", $p2, "/events"),
119 concat!("/orgs/", $p1, "/events"),
120 concat!("/users/", $p1, "/received_events"),
121 concat!("/users/", $p1, "/received_events/public"),
122 concat!("/users/", $p1, "/events"),
123 concat!("/users/", $p1, "/events/public"),
124 concat!("/users/", $p1, "/events/orgs/", $p2),
125 concat!("/feeds"),
126 concat!("/notifications"),
127 concat!("/repos/", $p1, "/", $p2, "/notifications"),
128 concat!("/notifications/threads/", $p1),
129 concat!("/notifications/threads/", $p1, "/subscription"),
130 concat!("/repos/", $p1, "/", $p2, "/stargazers"),
131 concat!("/users/", $p1, "/starred"),
132 concat!("/user/starred"),
133 concat!("/user/starred/", $p1, "/", $p2),
134 concat!("/repos/", $p1, "/", $p2, "/subscribers"),
135 concat!("/users/", $p1, "/subscriptions"),
136 concat!("/user/subscriptions"),
137 concat!("/repos/", $p1, "/", $p2, "/subscription"),
138 concat!("/user/subscriptions/", $p1, "/", $p2),
139 concat!("/users/", $p1, "/gists"),
140 concat!("/gists"),
141 concat!("/gists/", $p1),
142 concat!("/gists/", $p1, "/star"),
143 concat!("/repos/", $p1, "/", $p2, "/git/blobs/", $p3),
144 concat!("/repos/", $p1, "/", $p2, "/git/commits/", $p3),
145 concat!("/repos/", $p1, "/", $p2, "/git/refs"),
146 concat!("/repos/", $p1, "/", $p2, "/git/tags/", $p3),
147 concat!("/repos/", $p1, "/", $p2, "/git/trees/", $p3),
148 concat!("/issues"),
149 concat!("/user/issues"),
150 concat!("/orgs/", $p1, "/issues"),
151 concat!("/repos/", $p1, "/", $p2, "/issues"),
152 concat!("/repos/", $p1, "/", $p2, "/issues/", $p3),
153 concat!("/repos/", $p1, "/", $p2, "/assignees"),
154 concat!("/repos/", $p1, "/", $p2, "/assignees/", $p3),
155 concat!("/repos/", $p1, "/", $p2, "/issues/", $p3, "/comments"),
156 concat!("/repos/", $p1, "/", $p2, "/issues/", $p3, "/events"),
157 concat!("/repos/", $p1, "/", $p2, "/labels"),
158 concat!("/repos/", $p1, "/", $p2, "/labels/", $p3),
159 concat!("/repos/", $p1, "/", $p2, "/issues/", $p3, "/labels"),
160 concat!("/repos/", $p1, "/", $p2, "/milestones/", $p3, "/labels"),
161 concat!("/repos/", $p1, "/", $p2, "/milestones/"),
162 concat!("/repos/", $p1, "/", $p2, "/milestones/", $p3),
163 concat!("/emojis"),
164 concat!("/gitignore/templates"),
165 concat!("/gitignore/templates/", $p1),
166 concat!("/meta"),
167 concat!("/rate_limit"),
168 concat!("/users/", $p1, "/orgs"),
169 concat!("/user/orgs"),
170 concat!("/orgs/", $p1),
171 concat!("/orgs/", $p1, "/members"),
172 concat!("/orgs/", $p1, "/members", $p2),
173 concat!("/orgs/", $p1, "/public_members"),
174 concat!("/orgs/", $p1, "/public_members/", $p2),
175 concat!("/orgs/", $p1, "/teams"),
176 concat!("/teams/", $p1),
177 concat!("/teams/", $p1, "/members"),
178 concat!("/teams/", $p1, "/members", $p2),
179 concat!("/teams/", $p1, "/repos"),
180 concat!("/teams/", $p1, "/repos/", $p2, "/", $p3),
181 concat!("/user/teams"),
182 concat!("/repos/", $p1, "/", $p2, "/pulls"),
183 concat!("/repos/", $p1, "/", $p2, "/pulls/", $p3),
184 concat!("/repos/", $p1, "/", $p2, "/pulls/", $p3, "/commits"),
185 concat!("/repos/", $p1, "/", $p2, "/pulls/", $p3, "/files"),
186 concat!("/repos/", $p1, "/", $p2, "/pulls/", $p3, "/merge"),
187 concat!("/repos/", $p1, "/", $p2, "/pulls/", $p3, "/comments"),
188 concat!("/user/repos"),
189 concat!("/users/", $p1, "/repos"),
190 concat!("/orgs/", $p1, "/repos"),
191 concat!("/repositories"),
192 concat!("/repos/", $p1, "/", $p2),
193 concat!("/repos/", $p1, "/", $p2, "/contributors"),
194 concat!("/repos/", $p1, "/", $p2, "/languages"),
195 concat!("/repos/", $p1, "/", $p2, "/teams"),
196 concat!("/repos/", $p1, "/", $p2, "/tags"),
197 concat!("/repos/", $p1, "/", $p2, "/branches"),
198 concat!("/repos/", $p1, "/", $p2, "/branches/", $p3),
199 concat!("/repos/", $p1, "/", $p2, "/collaborators"),
200 concat!("/repos/", $p1, "/", $p2, "/collaborators/", $p3),
201 concat!("/repos/", $p1, "/", $p2, "/comments"),
202 concat!("/repos/", $p1, "/", $p2, "/commits/", $p3, "/comments"),
203 concat!("/repos/", $p1, "/", $p2, "/commits"),
204 concat!("/repos/", $p1, "/", $p2, "/commits/", $p3),
205 concat!("/repos/", $p1, "/", $p2, "/readme"),
206 concat!("/repos/", $p1, "/", $p2, "/keys"),
207 concat!("/repos/", $p1, "/", $p2, "/keys", $p3),
208 concat!("/repos/", $p1, "/", $p2, "/downloads"),
209 concat!("/repos/", $p1, "/", $p2, "/downloads", $p3),
210 concat!("/repos/", $p1, "/", $p2, "/forks"),
211 concat!("/repos/", $p1, "/", $p2, "/hooks"),
212 concat!("/repos/", $p1, "/", $p2, "/hooks", $p3),
213 concat!("/repos/", $p1, "/", $p2, "/releases"),
214 concat!("/repos/", $p1, "/", $p2, "/releases/", $p3),
215 concat!("/repos/", $p1, "/", $p2, "/releases/", $p3, "/assets"),
216 concat!("/repos/", $p1, "/", $p2, "/stats/contributors"),
217 concat!("/repos/", $p1, "/", $p2, "/stats/commit_activity"),
218 concat!("/repos/", $p1, "/", $p2, "/stats/code_frequency"),
219 concat!("/repos/", $p1, "/", $p2, "/stats/participation"),
220 concat!("/repos/", $p1, "/", $p2, "/stats/punch_card"),
221 concat!("/repos/", $p1, "/", $p2, "/statuses/", $p3),
222 concat!("/search/repositories"),
223 concat!("/search/code"),
224 concat!("/search/issues"),
225 concat!("/search/users"),
226 concat!("/legacy/issues/search/", $p1, "/", $p2, "/", $p3, "/", $p4),
227 concat!("/legacy/repos/search/", $p1),
228 concat!("/legacy/user/search/", $p1),
229 concat!("/legacy/user/email/", $p1),
230 concat!("/users/", $p1),
231 concat!("/user"),
232 concat!("/users"),
233 concat!("/user/emails"),
234 concat!("/users/", $p1, "/followers"),
235 concat!("/user/followers"),
236 concat!("/users/", $p1, "/following"),
237 concat!("/user/following"),
238 concat!("/user/following/", $p1),
239 concat!("/users/", $p1, "/following", $p2),
240 concat!("/users/", $p1, "/keys"),
241 concat!("/user/keys"),
242 concat!("/user/keys/", $p1),
243 ]
244 }};
245 }
246
247 use register;
248