From 3ff3d19e71dbd5b103bb0e1a02f6610b721c319c Mon Sep 17 00:00:00 2001 From: Mikolaj Figurski Date: Wed, 11 Jan 2023 15:38:20 -0500 Subject: [PATCH 1/5] Create basic bench structure --- benches/bench.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 benches/bench.rs diff --git a/benches/bench.rs b/benches/bench.rs new file mode 100644 index 0000000..ab694d6 --- /dev/null +++ b/benches/bench.rs @@ -0,0 +1,66 @@ +#![feature(test)] + +extern crate test; +use test::Bencher; +extern crate range_bounds_map; +use std::ops::Range; + +use range_bounds_map::*; + +/// linear multiplier for work done by benchmarks +const REPEAT: usize = 100; + +fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { + let mut map = RangeBoundsMap::new(); + for i in 0..n { + if let Err(OverlapError) = map.insert_platonic((2 * i)..(2 * i + 1), i) + { + panic!("Failed to insert") + } + } + map +} + +#[bench] +fn bench_insert_platonic(b: &mut Bencher) { + b.iter(|| { + let mut map = RangeBoundsMap::new(); + for i in 0..REPEAT { + let r = (2 * i)..(2 * i + 1); + if let Err(OverlapError) = map.insert_platonic(r, i) { + panic!("Failed to insert") + } + } + }); +} + +#[bench] +fn bench_overlaps(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.overlapping(&(0..2 * REPEAT)) {}) +} + +#[bench] +fn bench_get_entry_at_point(b: &mut Bencher) { + b.iter(|| {}) +} + +#[bench] +fn bench_iter(b: &mut Bencher) { + b.iter(|| {}) +} + +#[bench] +fn bench_remove_overlapping(b: &mut Bencher) { + b.iter(|| {}) +} + +#[bench] +fn bench_cut(b: &mut Bencher) { + b.iter(|| {}) +} + +#[bench] +fn bench_gaps(b: &mut Bencher) { + b.iter(|| {}) +} From 38ffd6801f78307219d6f5e6835fc7a6873c7377 Mon Sep 17 00:00:00 2001 From: Mikolaj Figurski Date: Thu, 12 Jan 2023 12:35:06 -0500 Subject: [PATCH 2/5] Benchmark all inserts --- benches/bench.rs | 64 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index ab694d6..a7dbcf1 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -10,11 +10,11 @@ use range_bounds_map::*; /// linear multiplier for work done by benchmarks const REPEAT: usize = 100; +/// utility for constructing identity [i,i]->i map for benches fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { let mut map = RangeBoundsMap::new(); for i in 0..n { - if let Err(OverlapError) = map.insert_platonic((2 * i)..(2 * i + 1), i) - { + if let Err(OverlapError) = map.insert_platonic(i..i + 1, i) { panic!("Failed to insert") } } @@ -26,23 +26,69 @@ fn bench_insert_platonic(b: &mut Bencher) { b.iter(|| { let mut map = RangeBoundsMap::new(); for i in 0..REPEAT { - let r = (2 * i)..(2 * i + 1); + let r = i..=i; if let Err(OverlapError) = map.insert_platonic(r, i) { - panic!("Failed to insert") + panic!("Failed to insert"); } } }); } #[bench] -fn bench_overlaps(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.overlapping(&(0..2 * REPEAT)) {}) +fn bench_insert_coalesce_touching(b: &mut Bencher) { + b.iter(|| { + let mut map = RangeBoundsMap::new(); + for i in 0..REPEAT / 2 { + let r1 = (10 * i)..(10 * i + 1); + let r2 = (10 * i + 1)..(10 * i + 2); + if let Err(e) = map.insert_coalesce_touching(r1, true) { + panic!("Failed to insert: {:?}", e) + } + if let Err(e) = map.insert_coalesce_touching(r2, true) { + panic!("Failed to insert: {:?}", e) + } + } + }) } #[bench] -fn bench_get_entry_at_point(b: &mut Bencher) { - b.iter(|| {}) +fn bench_insert_coalesce_overlapping(b: &mut Bencher) { + b.iter(|| { + let mut map = RangeBoundsMap::new(); + for i in 0..REPEAT / 2 { + let r1 = (10 * i)..(10 * i + 1); + let r2 = (10 * i)..(10 * i + 2); + if let Err(e) = map.insert_coalesce_overlapping(r1, true) { + panic!("Failed to insert: {:?}", e) + } + if let Err(e) = map.insert_coalesce_overlapping(r2, true) { + panic!("Failed to insert: {:?}", e) + } + } + }) +} + +#[bench] +fn bench_insert_coalesce_touching_or_overlapping(b: &mut Bencher) { + b.iter(|| { + let mut map = RangeBoundsMap::new(); + for i in 0..REPEAT / 2 { + let r1 = (10 * i + 1)..(10 * i + 2); + let r2 = (10 * i)..(10 * i + 4); + if let Err(e) = map.insert_coalesce_touching_or_overlapping(r1, 1) { + panic!("Failed to insert: {:?}", e) + } + if let Err(e) = map.insert_coalesce_touching_or_overlapping(r2, 2) { + panic!("Failed to insert: {:?}", e) + } + } + }) +} + +#[bench] +fn bench_overlaps(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.overlapping(&(0..2 * REPEAT)) {}) } #[bench] From 601476f855ea696c3c069d909cab393328fe9bc2 Mon Sep 17 00:00:00 2001 From: Mikolaj Figurski Date: Thu, 12 Jan 2023 15:57:26 -0500 Subject: [PATCH 3/5] Fill in significant function benches --- benches/bench.rs | 43 ++++++++++++++++++++++++++++++++++------- src/range_bounds_map.rs | 2 +- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index a7dbcf1..b73bec8 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -3,12 +3,12 @@ extern crate test; use test::Bencher; extern crate range_bounds_map; -use std::ops::Range; +use std::ops::{Bound, Range}; use range_bounds_map::*; /// linear multiplier for work done by benchmarks -const REPEAT: usize = 100; +const REPEAT: usize = 120; /// utility for constructing identity [i,i]->i map for benches fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { @@ -88,25 +88,54 @@ fn bench_insert_coalesce_touching_or_overlapping(b: &mut Bencher) { #[bench] fn bench_overlaps(b: &mut Bencher) { let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.overlapping(&(0..2 * REPEAT)) {}) + b.iter(|| for _ in map.overlapping(&(0..REPEAT)) {}) } #[bench] fn bench_iter(b: &mut Bencher) { - b.iter(|| {}) + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.iter() {}) } #[bench] fn bench_remove_overlapping(b: &mut Bencher) { - b.iter(|| {}) + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + for _ in map.remove_overlapping(&(0..REPEAT)) {} + }) } #[bench] fn bench_cut(b: &mut Bencher) { - b.iter(|| {}) + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + if let Err(e) = map.cut(&(0..REPEAT)) { + panic!("Failed to cut: {:?}", e) + } + }) } #[bench] fn bench_gaps(b: &mut Bencher) { - b.iter(|| {}) + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.gaps(&(0..REPEAT)) {}) +} + +#[bench] +fn bench_split_off(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + if let Err(e) = map.split_off(Bound::Included(REPEAT / 2)) { + panic!("Failed to split: {:?}", e) + } + }) +} + +#[bench] +fn bench_overlapping_trimmed(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.overlapping_trimmed(&(1..REPEAT - 1)) {}) } diff --git a/src/range_bounds_map.rs b/src/range_bounds_map.rs index fe70d53..dbfa684 100644 --- a/src/range_bounds_map.rs +++ b/src/range_bounds_map.rs @@ -1412,7 +1412,7 @@ where } /// Moves all elements from `other` into `self` by - /// [`RangeBoundsMap::insert_platonic()`] in acending order, + /// [`RangeBoundsMap::insert_platonic()`] in ascending order, /// leaving `other` empty. /// /// If any of the `RangeBounds` in `other` overlap `self` then From 2ec94c6158d84ff9009c6a0b89995ed9e4c41431 Mon Sep 17 00:00:00 2001 From: Mikolaj Figurski Date: Thu, 12 Jan 2023 16:23:54 -0500 Subject: [PATCH 4/5] Separate benchmark categories --- benches/{bench.rs => insert.rs} | 69 +---------------------------- benches/operations.rs | 78 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 68 deletions(-) rename benches/{bench.rs => insert.rs} (53%) create mode 100644 benches/operations.rs diff --git a/benches/bench.rs b/benches/insert.rs similarity index 53% rename from benches/bench.rs rename to benches/insert.rs index b73bec8..71e06e1 100644 --- a/benches/bench.rs +++ b/benches/insert.rs @@ -2,25 +2,13 @@ extern crate test; use test::Bencher; -extern crate range_bounds_map; -use std::ops::{Bound, Range}; +extern crate range_bounds_map; use range_bounds_map::*; /// linear multiplier for work done by benchmarks const REPEAT: usize = 120; -/// utility for constructing identity [i,i]->i map for benches -fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { - let mut map = RangeBoundsMap::new(); - for i in 0..n { - if let Err(OverlapError) = map.insert_platonic(i..i + 1, i) { - panic!("Failed to insert") - } - } - map -} - #[bench] fn bench_insert_platonic(b: &mut Bencher) { b.iter(|| { @@ -84,58 +72,3 @@ fn bench_insert_coalesce_touching_or_overlapping(b: &mut Bencher) { } }) } - -#[bench] -fn bench_overlaps(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.overlapping(&(0..REPEAT)) {}) -} - -#[bench] -fn bench_iter(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.iter() {}) -} - -#[bench] -fn bench_remove_overlapping(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| { - let mut map = map.clone(); - for _ in map.remove_overlapping(&(0..REPEAT)) {} - }) -} - -#[bench] -fn bench_cut(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| { - let mut map = map.clone(); - if let Err(e) = map.cut(&(0..REPEAT)) { - panic!("Failed to cut: {:?}", e) - } - }) -} - -#[bench] -fn bench_gaps(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.gaps(&(0..REPEAT)) {}) -} - -#[bench] -fn bench_split_off(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| { - let mut map = map.clone(); - if let Err(e) = map.split_off(Bound::Included(REPEAT / 2)) { - panic!("Failed to split: {:?}", e) - } - }) -} - -#[bench] -fn bench_overlapping_trimmed(b: &mut Bencher) { - let map = build_identity_map(REPEAT); - b.iter(|| for _ in map.overlapping_trimmed(&(1..REPEAT - 1)) {}) -} diff --git a/benches/operations.rs b/benches/operations.rs new file mode 100644 index 0000000..3cc42c2 --- /dev/null +++ b/benches/operations.rs @@ -0,0 +1,78 @@ +#![feature(test)] + +use std::ops::{Bound, Range}; + +extern crate test; +use test::Bencher; + +extern crate range_bounds_map; +use range_bounds_map::*; + +/// linear multiplier for work done by benchmarks +const REPEAT: usize = 120; + +/// utility for constructing identity [i,i]->i map for benches +fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { + let mut map = RangeBoundsMap::new(); + for i in 0..n { + if let Err(OverlapError) = map.insert_platonic(i..i + 1, i) { + panic!("Failed to insert") + } + } + map +} + +#[bench] +fn bench_overlaps(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.overlapping(&(0..REPEAT)) {}) +} + +#[bench] +fn bench_iter(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.iter() {}) +} + +#[bench] +fn bench_remove_overlapping(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + for _ in map.remove_overlapping(&(0..REPEAT)) {} + }) +} + +#[bench] +fn bench_cut(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + if let Err(e) = map.cut(&(0..REPEAT)) { + panic!("Failed to cut: {:?}", e) + } + }) +} + +#[bench] +fn bench_gaps(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.gaps(&(0..REPEAT)) {}) +} + +#[bench] +fn bench_split_off(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| { + let mut map = map.clone(); + if let Err(e) = map.split_off(Bound::Included(REPEAT / 2)) { + panic!("Failed to split: {:?}", e) + } + }) +} + +#[bench] +fn bench_overlapping_trimmed(b: &mut Bencher) { + let map = build_identity_map(REPEAT); + b.iter(|| for _ in map.overlapping_trimmed(&(1..REPEAT - 1)) {}) +} From 1ea738bd79d8cedf48900ef3dc40ac5e736b1388 Mon Sep 17 00:00:00 2001 From: Mikolaj Figurski Date: Fri, 13 Jan 2023 14:01:51 -0500 Subject: [PATCH 5/5] Refactor, bench overwrite --- benches/insert.rs | 45 +++++++++++++++++++++++-------------------- benches/operations.rs | 13 ++++--------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/benches/insert.rs b/benches/insert.rs index 71e06e1..0d0c89e 100644 --- a/benches/insert.rs +++ b/benches/insert.rs @@ -15,9 +15,7 @@ fn bench_insert_platonic(b: &mut Bencher) { let mut map = RangeBoundsMap::new(); for i in 0..REPEAT { let r = i..=i; - if let Err(OverlapError) = map.insert_platonic(r, i) { - panic!("Failed to insert"); - } + map.insert_platonic(r, i).expect("insert failed"); } }); } @@ -29,12 +27,10 @@ fn bench_insert_coalesce_touching(b: &mut Bencher) { for i in 0..REPEAT / 2 { let r1 = (10 * i)..(10 * i + 1); let r2 = (10 * i + 1)..(10 * i + 2); - if let Err(e) = map.insert_coalesce_touching(r1, true) { - panic!("Failed to insert: {:?}", e) - } - if let Err(e) = map.insert_coalesce_touching(r2, true) { - panic!("Failed to insert: {:?}", e) - } + map.insert_coalesce_touching(r1, true) + .expect("Failed to insert"); + map.insert_coalesce_touching(r2, true) + .expect("Failed to insert"); } }) } @@ -46,12 +42,10 @@ fn bench_insert_coalesce_overlapping(b: &mut Bencher) { for i in 0..REPEAT / 2 { let r1 = (10 * i)..(10 * i + 1); let r2 = (10 * i)..(10 * i + 2); - if let Err(e) = map.insert_coalesce_overlapping(r1, true) { - panic!("Failed to insert: {:?}", e) - } - if let Err(e) = map.insert_coalesce_overlapping(r2, true) { - panic!("Failed to insert: {:?}", e) - } + map.insert_coalesce_overlapping(r1, true) + .expect("Failed to insert"); + map.insert_coalesce_overlapping(r2, true) + .expect("Failed to insert"); } }) } @@ -63,12 +57,21 @@ fn bench_insert_coalesce_touching_or_overlapping(b: &mut Bencher) { for i in 0..REPEAT / 2 { let r1 = (10 * i + 1)..(10 * i + 2); let r2 = (10 * i)..(10 * i + 4); - if let Err(e) = map.insert_coalesce_touching_or_overlapping(r1, 1) { - panic!("Failed to insert: {:?}", e) - } - if let Err(e) = map.insert_coalesce_touching_or_overlapping(r2, 2) { - panic!("Failed to insert: {:?}", e) - } + map.insert_coalesce_touching_or_overlapping(r1, 1) + .expect("Failed to insert"); + map.insert_coalesce_touching_or_overlapping(r2, 2) + .expect("Failed to insert"); } }) } + +#[bench] +fn bench_overwrite(b: &mut Bencher) { + b.iter(|| { + let mut map = RangeBoundsMap::new(); + for i in 0..REPEAT { + let r = i..i + 2; + map.overwrite(r, i).expect("insert failed"); + } + }); +} diff --git a/benches/operations.rs b/benches/operations.rs index 3cc42c2..a6d36ff 100644 --- a/benches/operations.rs +++ b/benches/operations.rs @@ -15,9 +15,7 @@ const REPEAT: usize = 120; fn build_identity_map(n: usize) -> RangeBoundsMap, usize> { let mut map = RangeBoundsMap::new(); for i in 0..n { - if let Err(OverlapError) = map.insert_platonic(i..i + 1, i) { - panic!("Failed to insert") - } + map.insert_platonic(i..i + 1, i).expect("insert failed"); } map } @@ -48,9 +46,7 @@ fn bench_cut(b: &mut Bencher) { let map = build_identity_map(REPEAT); b.iter(|| { let mut map = map.clone(); - if let Err(e) = map.cut(&(0..REPEAT)) { - panic!("Failed to cut: {:?}", e) - } + for _ in map.cut(&(0..REPEAT)).expect("Failed to cut") {} }) } @@ -65,9 +61,8 @@ fn bench_split_off(b: &mut Bencher) { let map = build_identity_map(REPEAT); b.iter(|| { let mut map = map.clone(); - if let Err(e) = map.split_off(Bound::Included(REPEAT / 2)) { - panic!("Failed to split: {:?}", e) - } + map.split_off(Bound::Included(REPEAT / 2)) + .expect("Failed to split"); }) }