Skip to content

Commit 0cbfe52

Browse files
committed
feat(libredirection): improve performance for building action, testing and creating impact
1 parent 0b01af2 commit 0cbfe52

32 files changed

+872
-210
lines changed

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ tera = "1.19.1"
2525
default = ["compress", "router"]
2626
compress = ["dep:brotli", "dep:flate2"]
2727
router = []
28+
dot = ["dep:dot_graph"]
2829

2930
[dependencies]
3031
brotli = { version = "3.4.0", optional = true }
3132
cfg-if = "1.0.0"
3233
chrono = { version = "0.4.31", features = ["serde"] }
3334
cidr = { version = "0.2.2", features = ["serde"] }
35+
dot_graph = { version = "0.2.3", optional = true }
3436
flate2 = { version = "1.0.27", optional = true }
3537
heck = "0.4.1"
3638
http = "0.2.9"
@@ -66,6 +68,10 @@ harness = false
6668
name = "filter_body_benchmark"
6769
harness = false
6870

71+
[[bench]]
72+
name = "test_examples_benchmark"
73+
harness = false
74+
6975
[dependencies.web-sys]
7076
version = "0.3"
7177
features = [

benches/build_router_rule_benchmark.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
#[macro_use]
22
extern crate criterion;
3+
34
use criterion::{BatchSize, BenchmarkId, Criterion};
5+
use flate2::read::GzDecoder;
46
use redirectionio::api::{Rule, RulesMessage};
57
use redirectionio::router::{Router, RouterConfig};
6-
use std::fs::read_to_string;
8+
use std::fs::File;
79

810
fn create_rules(filename: String) -> RulesMessage {
9-
let content = read_to_string(filename).expect("Cannot open file");
10-
let rules: RulesMessage = serde_json::from_str(content.as_str()).expect("Cannot deserialize");
11+
let content_gzip = File::open(filename.clone()).expect("Cannot open file");
12+
let rules: RulesMessage = serde_json::from_reader(GzDecoder::new(content_gzip)).expect("Cannot deserialize");
1113

1214
rules
1315
}
1416

1517
fn build_router_bench(c: &mut Criterion) {
1618
let files = vec![
17-
"../bench-files/large-rules-1k.json".to_string(),
18-
"../bench-files/large-rules-10k.json".to_string(),
19-
"../bench-files/large-rules-50k.json".to_string(),
20-
"../bench-files/large-rules-150k.json".to_string(),
21-
"../bench-files/large-rules-200k.json".to_string(),
19+
"../bench-files/large-rules-1k.json.gz".to_string(),
20+
"../bench-files/large-rules-10k.json.gz".to_string(),
21+
"../bench-files/large-rules-50k.json.gz".to_string(),
22+
"../bench-files/large-rules-150k.json.gz".to_string(),
23+
"../bench-files/large-rules-200k.json.gz".to_string(),
24+
"../bench-files/large-rules-210k.json.gz".to_string(),
2225
];
2326

2427
let mut group = c.benchmark_group("router_builder");
@@ -31,10 +34,15 @@ fn build_router_bench(c: &mut Criterion) {
3134
|rules| {
3235
let config = RouterConfig::default();
3336
let mut router = Router::<Rule>::from_config(config.clone());
37+
let rules_len = rules.rules.len();
3438

3539
for rule in rules.rules {
36-
router.insert(rule.into_route(&config));
40+
router.insert(rule);
3741
}
42+
43+
router.cache(10_000);
44+
45+
assert_eq!(router.len(), rules_len);
3846
},
3947
BatchSize::NumIterations(1),
4048
);

benches/filter_body_benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use criterion::{BenchmarkId, Criterion};
77
use redirectionio::action::Action;
88
use redirectionio::api::Rule;
99
use redirectionio::http::{Header, Request};
10-
use redirectionio::router::RouterConfig;
10+
use redirectionio::router::{IntoRoute, RouterConfig};
1111
use std::io::Write;
1212
use std::sync::Arc;
1313

benches/match_rule_benchmark.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
#[macro_use]
22
extern crate criterion;
33
use criterion::{BenchmarkId, Criterion};
4+
use flate2::read::GzDecoder;
45
use redirectionio::action::{Action, UnitTrace};
56
use redirectionio::api::{Rule, RulesMessage};
67
use redirectionio::http::Request;
78
use redirectionio::router::{Router, RouterConfig};
8-
use std::fs::read_to_string;
9+
use std::fs::File;
910

1011
fn create_router(filename: String, config: &RouterConfig) -> Router<Rule> {
11-
let content = read_to_string(filename).expect("Cannot open file");
12-
let rules: RulesMessage = serde_json::from_str(content.as_str()).expect("Cannot deserialize");
13-
let mut router = Router::<Rule>::default();
12+
let content_gzip = File::open(filename.clone()).expect("Cannot open file");
13+
let rules: RulesMessage = serde_json::from_reader(GzDecoder::new(content_gzip)).expect("Cannot deserialize");
14+
let mut router = Router::<Rule>::from_config(config.clone());
1415

1516
for rule in rules.rules {
16-
router.insert(rule.into_route(config))
17+
router.insert(rule)
1718
}
1819

1920
router
2021
}
2122

2223
fn no_match_bench(c: &mut Criterion) {
2324
let files = vec![
24-
"../bench-files/large-rules-1k.json".to_string(),
25-
"../bench-files/large-rules-10k.json".to_string(),
26-
"../bench-files/large-rules-50k.json".to_string(),
27-
"../bench-files/large-rules-150k.json".to_string(),
28-
"../bench-files/large-rules-200k.json".to_string(),
25+
"../bench-files/large-rules-1k.json.gz".to_string(),
26+
"../bench-files/large-rules-10k.json.gz".to_string(),
27+
"../bench-files/large-rules-50k.json.gz".to_string(),
28+
"../bench-files/large-rules-150k.json.gz".to_string(),
29+
"../bench-files/large-rules-200k.json.gz".to_string(),
30+
"../bench-files/large-rules-210k.json.gz".to_string(),
2931
];
3032

3133
let mut group = c.benchmark_group("no_match");
@@ -48,11 +50,12 @@ fn no_match_bench(c: &mut Criterion) {
4850

4951
fn no_match_cache_bench(c: &mut Criterion) {
5052
let files = vec![
51-
"../bench-files/large-rules-1k.json".to_string(),
52-
"../bench-files/large-rules-10k.json".to_string(),
53-
"../bench-files/large-rules-50k.json".to_string(),
54-
"../bench-files/large-rules-150k.json".to_string(),
55-
"../bench-files/large-rules-200k.json".to_string(),
53+
"../bench-files/large-rules-1k.json.gz".to_string(),
54+
"../bench-files/large-rules-10k.json.gz".to_string(),
55+
"../bench-files/large-rules-50k.json.gz".to_string(),
56+
"../bench-files/large-rules-150k.json.gz".to_string(),
57+
"../bench-files/large-rules-200k.json.gz".to_string(),
58+
"../bench-files/large-rules-210k.json.gz".to_string(),
5659
];
5760

5861
let mut group = c.benchmark_group("no_match_cache");
@@ -77,7 +80,7 @@ fn no_match_cache_bench(c: &mut Criterion) {
7780

7881
fn match_rule_in_200k(c: &mut Criterion) {
7982
let config = RouterConfig::default();
80-
let mut router = create_router("../bench-files/large-rules-200k.json".to_string(), &config);
83+
let mut router = create_router("../bench-files/large-rules-200k.json.gz".to_string(), &config);
8184
let request = Request::from_config(
8285
&config,
8386
"/sites/default/files/image-gallery/lowtideonuseppaimage000000edited_0.jpg".to_string(),
@@ -104,7 +107,7 @@ fn match_rule_in_200k(c: &mut Criterion) {
104107

105108
fn build_action_rule_in_200k(c: &mut Criterion) {
106109
let config = RouterConfig::default();
107-
let mut router = create_router("../bench-files/large-rules-200k.json".to_string(), &config);
110+
let mut router = create_router("../bench-files/large-rules-200k.json.gz".to_string(), &config);
108111
let request = Request::from_config(
109112
&config,
110113
"/sites/default/files/image-gallery/lowtideonuseppaimage000000edited_0.jpg".to_string(),
@@ -156,7 +159,7 @@ fn build_action_rule_in_200k(c: &mut Criterion) {
156159

157160
fn impact(c: &mut Criterion) {
158161
let config = RouterConfig::default();
159-
let mut router = create_router("../bench-files/large-rules-200k.json".to_string(), &config);
162+
let mut router = create_router("../bench-files/large-rules-200k.json.gz".to_string(), &config);
160163
let request = Request::from_config(
161164
&config,
162165
"/sites/default/files/image-gallery/lowtideonuseppaimage000000edited_0.jpg".to_string(),

benches/perf.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{fs::File, os::raw::c_int, path::Path};
22

33
use criterion::profiler::Profiler;
4-
use pprof::ProfilerGuard;
4+
use pprof::{ProfilerGuard, ProfilerGuardBuilder};
55

66
/// Small custom profiler that can be used with Criterion to create a flamegraph for benchmarks.
77
/// Also see [the Criterion documentation on this][custom-profiler].
@@ -52,12 +52,13 @@ impl<'a> FlamegraphProfiler<'a> {
5252

5353
impl<'a> Profiler for FlamegraphProfiler<'a> {
5454
fn start_profiling(&mut self, _benchmark_id: &str, _benchmark_dir: &Path) {
55-
self.active_profiler = Some(ProfilerGuard::new(self.frequency).unwrap());
55+
let profiler = ProfilerGuardBuilder::default().frequency(self.frequency).build().unwrap();
56+
57+
self.active_profiler = Some(profiler);
5658
}
5759

58-
fn stop_profiling(&mut self, _benchmark_id: &str, benchmark_dir: &Path) {
59-
std::fs::create_dir_all(benchmark_dir).unwrap();
60-
let flamegraph_path = benchmark_dir.join("flamegraph.svg");
60+
fn stop_profiling(&mut self, _benchmark_id: &str, _benchmark_dir: &Path) {
61+
let flamegraph_path = Path::new("flamegraph.svg");
6162
let flamegraph_file = File::create(flamegraph_path).expect("File system error while creating flamegraph.svg");
6263
if let Some(profiler) = self.active_profiler.take() {
6364
profiler

benches/test_examples_benchmark.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#[macro_use]
2+
extern crate criterion;
3+
use criterion::{BenchmarkId, Criterion};
4+
use flate2::read::GzDecoder;
5+
use redirectionio::api::{Rule, RuleChangeSet, RulesMessage, TestExamplesOutput, TestExamplesProjectInput};
6+
use redirectionio::router::{Router, RouterConfig};
7+
use std::fs::File;
8+
9+
mod perf;
10+
11+
fn test_examples_bench(c: &mut Criterion) {
12+
let files = vec!["../bench-files/large-rules-210k.json.gz".to_string()];
13+
14+
let mut group = c.benchmark_group("no_match");
15+
group.sample_size(10);
16+
17+
for filename in files {
18+
let config = RouterConfig::default();
19+
let content_gzip = File::open(filename.clone()).expect("Cannot open file");
20+
let rules: RulesMessage = serde_json::from_reader(GzDecoder::new(content_gzip)).expect("Cannot deserialize");
21+
let mut router = Router::<Rule>::from_config(config.clone());
22+
23+
for rule in rules.rules {
24+
router.insert(rule)
25+
}
26+
27+
router.cache(10_000);
28+
29+
let arc_router = std::sync::Arc::new(router);
30+
31+
group.bench_with_input(BenchmarkId::from_parameter(filename.clone()), &filename, |b, _f| {
32+
b.iter(|| {
33+
TestExamplesOutput::from_project(
34+
TestExamplesProjectInput {
35+
change_set: RuleChangeSet::default(),
36+
},
37+
arc_router.clone(),
38+
);
39+
});
40+
});
41+
}
42+
43+
group.finish();
44+
}
45+
46+
criterion_group! {
47+
name = benches;
48+
config = Criterion::default().with_profiler(perf::FlamegraphProfiler::new(99));
49+
targets = test_examples_bench
50+
}
51+
criterion_main!(benches);

0 commit comments

Comments
 (0)