diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d88ac9..c6fa6e9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,6 +15,7 @@ jobs: - run: cargo test - run: cargo test --features preserve_order - run: cargo test --manifest-path test-suite/Cargo.toml + - run: cargo bench rustfmt: name: Rustfmt diff --git a/test-suite/Cargo.toml b/test-suite/Cargo.toml index 9f500b3..4d539c8 100644 --- a/test-suite/Cargo.toml +++ b/test-suite/Cargo.toml @@ -5,7 +5,12 @@ authors = ["Alex Crichton "] publish = false edition = "2018" +[[bench]] +name = "linear" +harness = false + [dev-dependencies] +bencher = "0.1" toml = { path = ".." } serde = { version = "1.0", features = ["derive"] } serde_derive = "1.0" diff --git a/test-suite/benches/linear.rs b/test-suite/benches/linear.rs new file mode 100644 index 0000000..1553595 --- /dev/null +++ b/test-suite/benches/linear.rs @@ -0,0 +1,35 @@ +// Regressoion test for https://github.com/alexcrichton/toml-rs/issues/342 + +use bencher::{benchmark_group, benchmark_main, black_box, Bencher}; +use toml::Value; + +fn parse(bench: &mut Bencher, entries: usize, f: impl Fn(usize) -> String) { + let mut s = String::new(); + for i in 0..entries { + s += &f(i); + s += "entry = 42\n" + } + let s = black_box(s); + bench.iter(|| { + black_box(s.parse::().unwrap()); + }) +} + +fn map_10(bench: &mut Bencher) { + parse(bench, 10, |i| format!("[header_no_{}]\n", i)) +} + +fn map_100(bench: &mut Bencher) { + parse(bench, 100, |i| format!("[header_no_{}]\n", i)) +} + +fn array_10(bench: &mut Bencher) { + parse(bench, 10, |_i| "[[header]]\n".to_owned()) +} + +fn array_100(bench: &mut Bencher) { + parse(bench, 100, |_i| "[[header]]\n".to_owned()) +} + +benchmark_group!(benches, map_10, map_100, array_10, array_100); +benchmark_main!(benches); diff --git a/test-suite/tests/linear.rs b/test-suite/tests/linear.rs deleted file mode 100644 index dab51f9..0000000 --- a/test-suite/tests/linear.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::time::{Duration, Instant}; -use toml::Value; - -const TOLERANCE: f64 = 2.0; - -fn measure_time(entries: usize, f: impl Fn(usize) -> String) -> Duration { - let start = Instant::now(); - let mut s = String::new(); - for i in 0..entries { - s += &f(i); - s += "entry = 42\n" - } - s.parse::().unwrap(); - Instant::now() - start -} - -#[test] -fn linear_increase_map() { - let time_1 = measure_time(100, |i| format!("[header_no_{}]\n", i)); - let time_4 = measure_time(400, |i| format!("[header_no_{}]\n", i)); - dbg!(time_1, time_4); - // Now ensure that the deserialization time has increased linearly - // (within a tolerance interval) instead of, say, quadratically - assert!(time_4 > time_1.mul_f64(4.0 - TOLERANCE)); - assert!(time_4 < time_1.mul_f64(4.0 + TOLERANCE)); -} - -#[test] -fn linear_increase_array() { - let time_1 = measure_time(100, |i| format!("[[header_no_{}]]\n", i)); - let time_4 = measure_time(400, |i| format!("[[header_no_{}]]\n", i)); - dbg!(time_1, time_4); - // Now ensure that the deserialization time has increased linearly - // (within a tolerance interval) instead of, say, quadratically - assert!(time_4 > time_1.mul_f64(4.0 - TOLERANCE)); - assert!(time_4 < time_1.mul_f64(4.0 + TOLERANCE)); -}