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