diff --git a/Cargo.lock b/Cargo.lock index 1bfcc8d8..e11dc2bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2208,7 +2208,6 @@ dependencies = [ "ntex-router", "path-tree", "percent-encoding", - "regex", "route-recognizer", "routefinder", "smallvec", diff --git a/Cargo.toml b/Cargo.toml index cc8b0d43..7d85857d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,7 +82,6 @@ actix-router = "0.5.3" matchit = "0.8.3" ntex-router = "0.5.3" path-tree = "0.8.1" -regex = "1.10.6" route-recognizer = "0.3.1" routefinder = "0.5.4" xitca-router = "0.3.0" diff --git a/README.md b/README.md index d913c6b6..904a17e5 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,6 @@ In a router of 130 routes, benchmark matching 4 paths. | xitca-router | 415.02 ns | | ntex-router | 1.6291 µs | | route-recognizer | 4.3608 µs | -| regex | 4.5123 µs | | routefinder | 6.2077 µs | | actix-router | 20.722 µs | @@ -158,7 +157,6 @@ In a router of 320 routes, benchmark matching 80 paths. | ntex-router | 28.003 µs | | route-recognizer | 87.400 µs | | routefinder | 95.115 µs | -| regex | 117.12 µs | | actix-router | 176.11 µs | ## Inspirations diff --git a/benches/matchit.rs b/benches/matchit.rs index d65c80c9..6d854b62 100644 --- a/benches/matchit.rs +++ b/benches/matchit.rs @@ -5,6 +5,7 @@ use codspeed_criterion_compat::{criterion_group, criterion_main, Criterion}; use matchit_routes::paths; +use percent_encoding::percent_decode; pub mod matchit_routes; @@ -39,7 +40,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let mut path = actix_router::Path::new(route); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let mut path = actix_router::Path::new(route.as_ref()); actix.recognize(&mut path).unwrap(); let _ = path .iter() @@ -57,7 +59,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let at = matchit.at(route).unwrap(); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let at = matchit.at(route.as_ref()).unwrap(); let _ = at .params .iter() @@ -76,7 +79,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let mut path = ntex_router::Path::new(route); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let mut path = ntex_router::Path::new(route.as_ref()); ntex.recognize(&mut path).unwrap(); let _ = path .iter() @@ -94,7 +98,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let route = path_tree.find(route).unwrap(); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let route = path_tree.find(route.as_ref()).unwrap(); let _ = route .1 .params_iter() @@ -104,27 +109,6 @@ fn benchmark(criterion: &mut Criterion) { }); }); - group.bench_function("matchit benchmarks/regex", |bencher| { - let regex_set = regex::RegexSet::new(routes!(regex)).unwrap(); - let regexes: Vec<_> = routes!(regex) - .into_iter() - .map(|pattern| regex::Regex::new(pattern).unwrap()) - .collect(); - - bencher.iter(|| { - for route in paths() { - let matches = regex_set.matches(route).into_iter().collect::>(); - let index = matches.first().unwrap(); - let captures = regexes[*index].captures(route).unwrap(); - let _ = regexes[*index] - .capture_names() - .flatten() - .filter_map(|name| captures.name(name).map(|m| (name, m.as_str()))) - .collect::>(); - } - }); - }); - group.bench_function("matchit benchmarks/route-recognizer", |bencher| { let mut route_recognizer = route_recognizer::Router::new(); for route in routes!(colon) { @@ -133,7 +117,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let recognize = route_recognizer.recognize(route).unwrap(); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let recognize = route_recognizer.recognize(route.as_ref()).unwrap(); let _ = recognize .params() .iter() @@ -151,7 +136,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let best_match = routefinder.best_match(route).unwrap(); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let best_match = routefinder.best_match(route.as_ref()).unwrap(); let _ = best_match .captures() .iter() @@ -169,7 +155,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for route in paths() { - let at = xitca.at(route).unwrap(); + let route = percent_decode(route.as_bytes()).decode_utf8().unwrap(); + let at = xitca.at(route.as_ref()).unwrap(); let _ = at .params .iter() diff --git a/benches/matchit_routes.rs b/benches/matchit_routes.rs index 6b8643f6..43e3f2b2 100644 --- a/benches/matchit_routes.rs +++ b/benches/matchit_routes.rs @@ -4,7 +4,7 @@ pub fn paths() -> impl IntoIterator { "/user/repos", "/repos/rust-lang/rust/stargazers", "/orgs/rust-lang/public_members/nikomatsakis", - "/repos/rust-lang/rust/releases/1.51.0", + "/repos/rust-lang/rust/releases/1%2E51%2E0", ] } @@ -18,10 +18,6 @@ macro_rules! routes { routes!(finish => "{p1}", "{p2}", "{p3}", "{p4}") }}; - (regex) => {{ - routes!(finish => "(?.*)", "(?.*)", "(?.*)", "(?.*)") - }}; - (finish => $p1:literal, $p2:literal, $p3:literal, $p4:literal) => {{ [ concat!("/authorizations"), diff --git a/benches/path_tree.rs b/benches/path_tree.rs index 8e21ee29..522f00e0 100644 --- a/benches/path_tree.rs +++ b/benches/path_tree.rs @@ -5,6 +5,7 @@ use codspeed_criterion_compat::{criterion_group, criterion_main, Criterion}; use path_tree_routes::paths; +use percent_encoding::percent_decode; pub mod path_tree_routes; @@ -40,7 +41,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let mut path = actix_router::Path::new(path); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let mut path = actix_router::Path::new(path.as_ref()); let n = router.recognize(&mut path).unwrap(); assert_eq!(*n.0, index); let _ = path @@ -59,7 +61,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let n = matcher.at(path).unwrap(); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let n = matcher.at(path.as_ref()).unwrap(); assert_eq!(*n.value, index); let _ = n .params @@ -79,7 +82,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let mut path = ntex_router::Path::new(path); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let mut path = ntex_router::Path::new(path.as_ref()); let n = router.recognize(&mut path).unwrap(); assert_eq!(*n.0, index); let _ = path @@ -98,7 +102,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let n = tree.find(path).unwrap(); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let n = tree.find(path.as_ref()).unwrap(); assert_eq!(*n.0, index); let _ = n.1.params_iter() @@ -108,28 +113,6 @@ fn benchmark(criterion: &mut Criterion) { }); }); - group.bench_function("path-tree benchmarks/regex", |bencher| { - let regex_set = regex::RegexSet::new(routes!(regex)).unwrap(); - let regexes: Vec<_> = routes!(regex) - .into_iter() - .map(|pattern| regex::Regex::new(pattern).unwrap()) - .collect(); - - bencher.iter(|| { - for (index, path) in paths() { - let matches = regex_set.matches(path).into_iter().collect::>(); - assert!(matches.contains(&index)); - let i = matches.first().unwrap(); - let captures = regexes[*i].captures(path).unwrap(); - let _ = regexes[*i] - .capture_names() - .flatten() - .filter_map(|name| captures.name(name).map(|m| (name, m.as_str()))) - .collect::>(); - } - }); - }); - group.bench_function("path-tree benchmarks/route-recognizer", |bencher| { let mut router = route_recognizer::Router::::new(); for (index, route) in routes!(colon).iter().enumerate() { @@ -138,7 +121,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let n = router.recognize(path).unwrap(); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let n = router.recognize(path.as_ref()).unwrap(); assert_eq!(**n.handler(), index); let _ = n .params() @@ -157,7 +141,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let n = router.best_match(path).unwrap(); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let n = router.best_match(path.as_ref()).unwrap(); assert_eq!(*n, index); let _ = n .captures() @@ -176,7 +161,8 @@ fn benchmark(criterion: &mut Criterion) { bencher.iter(|| { for (index, path) in paths() { - let n = xitca.at(path).unwrap(); + let path = percent_decode(path.as_bytes()).decode_utf8().unwrap(); + let n = xitca.at(path.as_ref()).unwrap(); assert_eq!(*n.value, index); let _ = n .params diff --git a/benches/path_tree_routes.rs b/benches/path_tree_routes.rs index 7830d755..3aac7cbc 100644 --- a/benches/path_tree_routes.rs +++ b/benches/path_tree_routes.rs @@ -37,7 +37,7 @@ pub fn paths() -> impl IntoIterator { "/issues", "/legacy/issues/search/rust-lang/rust/987/1597", "/legacy/repos/search/1597", - "/legacy/user/email/rust@rust-lang.org", + "/legacy/user/email/rust%40rust-lang.org", "/legacy/user/search/1597", "/licenses", "/licenses/mit", @@ -96,10 +96,6 @@ macro_rules! routes { routes!(finish => "{p1}", "{p2}", "{p3}", "{p4}") }}; - (regex) => {{ - routes!(finish => "(?.*)", "(?.*)", "(?.*)", "(?.*)") - }}; - (finish => $p1:literal, $p2:literal, $p3:literal, $p4:literal) => {{ [ concat!("/app"),