From 3b7919007fa70ec28dfed911d4cc15e9eea372b8 Mon Sep 17 00:00:00 2001 From: Aria Shrimpton Date: Mon, 5 Feb 2024 14:03:00 +0000 Subject: fixed seed for benchmarks --- Tasks.org | 15 ----------- src/crates/benchmarker/benches/hashmap.rs | 7 ++++- src/crates/benchmarker/benches/linked_list.rs | 15 ++++++++--- src/crates/benchmarker/benches/vec.rs | 9 ++++--- src/crates/benchmarker/src/container.rs | 34 +++++++++++------------ src/crates/benchmarker/src/indexable.rs | 24 ++++++++--------- src/crates/benchmarker/src/lib.rs | 2 ++ src/crates/benchmarker/src/mapping.rs | 39 +++++++++++++-------------- src/crates/benchmarker/src/stack.rs | 16 +++++------ src/crates/candelabra/src/cost/benchmark.rs | 14 ++++++---- 10 files changed, 90 insertions(+), 85 deletions(-) diff --git a/Tasks.org b/Tasks.org index aa55cca..e75305a 100644 --- a/Tasks.org +++ b/Tasks.org @@ -119,21 +119,6 @@ We have the code to do all this end-to-end, and to run a 'brute force' for compa ie if we have two different ~insert/100 ...~ lines we should use both instead of only one. This will enable writing multiple scenarios per operation -** TODO Fix seed for benchmarks - -** TODO Fix benchmark_mapping not getting enough generic arguments - -#+BEGIN_SRC text -error[E0107]: function takes 3 generic arguments but 2 generic arguments were supplied - --> src/main.rs:6:29 - | -6 | candelabra_benchmarker::benchmark_mapping::, _>(&NS); - | ^^^^^^^^^^^^^^^^^ --------------------------------- - supplied 2 generic arguments - | | - | expected 3 generic arguments - | -#+END_SRC - * TODO Benchmarks & Evaluation We implement several test programs which require different data structures and different implementations. diff --git a/src/crates/benchmarker/benches/hashmap.rs b/src/crates/benchmarker/benches/hashmap.rs index dbd498a..908a5e6 100644 --- a/src/crates/benchmarker/benches/hashmap.rs +++ b/src/crates/benchmarker/benches/hashmap.rs @@ -1,7 +1,12 @@ +use rand::{rngs::StdRng, SeedableRng}; + fn main() { let ns = [ 64, 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 16384, 24576, 32768, 40960, 49152, 57344, 65536, ]; - candelabra_benchmarker::benchmark_mapping::, _, _>(&ns); + let mut rng = StdRng::seed_from_u64(42); + candelabra_benchmarker::benchmark_mapping::, _, _>( + &mut rng, &ns, + ); } diff --git a/src/crates/benchmarker/benches/linked_list.rs b/src/crates/benchmarker/benches/linked_list.rs index f2997e4..1c5de1f 100644 --- a/src/crates/benchmarker/benches/linked_list.rs +++ b/src/crates/benchmarker/benches/linked_list.rs @@ -1,9 +1,18 @@ +use rand::{rngs::StdRng, SeedableRng}; + fn main() { let ns = [ 64, 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 16384, 24576, 32768, 40960, 49152, 57344, 65536, ]; - candelabra_benchmarker::benchmark_container::, _>(&ns); - candelabra_benchmarker::benchmark_indexable::, _>(&ns); - candelabra_benchmarker::benchmark_stack::, _>(&ns); + let mut rng = StdRng::seed_from_u64(42); + candelabra_benchmarker::benchmark_container::, _>( + &mut rng, &ns, + ); + candelabra_benchmarker::benchmark_indexable::, _>( + &mut rng, &ns, + ); + candelabra_benchmarker::benchmark_stack::, _>( + &mut rng, &ns, + ); } diff --git a/src/crates/benchmarker/benches/vec.rs b/src/crates/benchmarker/benches/vec.rs index 0dd4637..f0f4d39 100644 --- a/src/crates/benchmarker/benches/vec.rs +++ b/src/crates/benchmarker/benches/vec.rs @@ -1,9 +1,12 @@ +use rand::{rngs::StdRng, SeedableRng}; + fn main() { let ns = [ 64, 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 16384, 24576, 32768, 40960, 49152, 57344, 65536, ]; - candelabra_benchmarker::benchmark_container::, _>(&ns); - candelabra_benchmarker::benchmark_indexable::, _>(&ns); - candelabra_benchmarker::benchmark_stack::, _>(&ns); + let mut rng = StdRng::seed_from_u64(42); + candelabra_benchmarker::benchmark_container::, _>(&mut rng, &ns); + candelabra_benchmarker::benchmark_indexable::, _>(&mut rng, &ns); + candelabra_benchmarker::benchmark_stack::, _>(&mut rng, &ns); } diff --git a/src/crates/benchmarker/src/container.rs b/src/crates/benchmarker/src/container.rs index 157ab90..82fa6f2 100644 --- a/src/crates/benchmarker/src/container.rs +++ b/src/crates/benchmarker/src/container.rs @@ -1,30 +1,30 @@ use primrose_library::traits::Container; -use rand::{distributions::Standard, prelude::Distribution, random, thread_rng, Rng}; +use rand::{distributions::Standard, prelude::Distribution, rngs::StdRng, Rng}; use crate::{benchmark_op, print_result}; -pub fn benchmark_container(ns: &[usize]) +pub fn benchmark_container(rng: &mut StdRng, ns: &[usize]) where T: Container + Default + Clone, E: Copy, Standard: Distribution, { for n in ns { - scenario_populate::(*n); - scenario_contains::(*n); - scenario_remove::(*n); - scenario_clear::(*n); + scenario_populate::(rng, *n); + scenario_contains::(rng, *n); + scenario_remove::(rng, *n); + scenario_clear::(rng, *n); } } -fn scenario_populate(n: usize) +fn scenario_populate(rng: &mut StdRng, n: usize) where T: Container + Default + Clone, E: Copy, Standard: Distribution, { let mut results = benchmark_op( - || (T::default(), (0..n).map(|_| random()).collect::>()), + || (T::default(), (0..n).map(|_| rng.gen()).collect::>()), |(c, xs)| { for x in xs { c.insert(*x); @@ -40,7 +40,7 @@ where print_result("insert", n, results); } -fn scenario_contains(n: usize) +fn scenario_contains(rng: &mut StdRng, n: usize) where T: Container + Default + Clone, E: Copy, @@ -48,7 +48,6 @@ where { let results = benchmark_op( || { - let mut rng = thread_rng(); let mut c = T::default(); // decide where the element that we will search for will be @@ -56,12 +55,12 @@ where // insert the element at pivot, and keep track of what it is for _ in 0..pivot { - c.insert(random()); + c.insert(rng.gen()); } let chosen = rng.gen(); c.insert(chosen); for _ in pivot..n { - c.insert(random()); + c.insert(rng.gen()); } (c, chosen) @@ -74,7 +73,7 @@ where print_result("contains", n, results); } -fn scenario_remove(n: usize) +fn scenario_remove(rng: &mut StdRng, n: usize) where T: Container + Default + Clone, E: Copy, @@ -82,7 +81,6 @@ where { let results = benchmark_op( || { - let mut rng = thread_rng(); let mut c = T::default(); // decide where the element that we will search for will be @@ -90,12 +88,12 @@ where // insert the element at pivot, and keep track of what it is for _ in 0..pivot { - c.insert(random()); + c.insert(rng.gen()); } let chosen = rng.gen(); c.insert(chosen); for _ in pivot..n { - c.insert(random()); + c.insert(rng.gen()); } (c, chosen) @@ -108,7 +106,7 @@ where print_result("remove", n, results); } -fn scenario_clear(n: usize) +fn scenario_clear(rng: &mut StdRng, n: usize) where T: Container + Default + Clone, E: Copy, @@ -118,7 +116,7 @@ where || { let mut c = T::default(); for _ in 0..n { - c.insert(random()); + c.insert(rng.gen()); } c diff --git a/src/crates/benchmarker/src/indexable.rs b/src/crates/benchmarker/src/indexable.rs index 196de6c..e00a8bc 100644 --- a/src/crates/benchmarker/src/indexable.rs +++ b/src/crates/benchmarker/src/indexable.rs @@ -1,24 +1,24 @@ use std::hint::black_box; use primrose_library::traits::{Container, Indexable}; -use rand::{distributions::Standard, prelude::Distribution, random, thread_rng, Rng}; +use rand::{distributions::Standard, prelude::Distribution, rngs::StdRng, Rng}; use crate::{benchmark_op, print_result}; -pub fn benchmark_indexable(ns: &[usize]) +pub fn benchmark_indexable(rng: &mut StdRng, ns: &[usize]) where T: Indexable + Container + Default + Clone, E: Copy, Standard: Distribution, { for n in ns { - scenario_first::(*n); - scenario_last::(*n); - scenario_nth::(*n); + scenario_first::(rng, *n); + scenario_last::(rng, *n); + scenario_nth::(rng, *n); } } -fn scenario_first(n: usize) +fn scenario_first(rng: &mut StdRng, n: usize) where T: Container + Indexable + Default + Clone, E: Copy, @@ -28,7 +28,7 @@ where || { let mut c = T::default(); for _ in 0..n { - c.insert(random()); + c.insert(rng.gen()); } c @@ -42,7 +42,7 @@ where print_result("first", n, results); } -fn scenario_last(n: usize) +fn scenario_last(rng: &mut StdRng, n: usize) where T: Container + Indexable + Default + Clone, E: Copy, @@ -52,7 +52,7 @@ where || { let mut c = T::default(); for _ in 0..n { - c.insert(random()); + c.insert(rng.gen()); } c @@ -66,7 +66,7 @@ where print_result("last", n, results); } -fn scenario_nth(n: usize) +fn scenario_nth(rng: &mut StdRng, n: usize) where T: Container + Indexable + Default + Clone, E: Copy, @@ -76,10 +76,10 @@ where || { let mut c = T::default(); for _ in 0..n { - c.insert(random()); + c.insert(rng.gen()); } - (c, thread_rng().gen_range(0..n)) + (c, rng.gen_range(0..n)) }, |(c, idx)| { let v = black_box(c.nth(*idx)); diff --git a/src/crates/benchmarker/src/lib.rs b/src/crates/benchmarker/src/lib.rs index f449527..ed2e85c 100644 --- a/src/crates/benchmarker/src/lib.rs +++ b/src/crates/benchmarker/src/lib.rs @@ -8,6 +8,8 @@ use std::{ time::{Duration, Instant}, }; +pub use rand; + pub use container::*; pub use indexable::*; pub use mapping::*; diff --git a/src/crates/benchmarker/src/mapping.rs b/src/crates/benchmarker/src/mapping.rs index b567b30..0932a50 100644 --- a/src/crates/benchmarker/src/mapping.rs +++ b/src/crates/benchmarker/src/mapping.rs @@ -1,12 +1,13 @@ use primrose_library::traits::Mapping; use rand::{ distributions::{Distribution, Standard}, - random, thread_rng, Rng, + rngs::StdRng, + Rng, }; use crate::{benchmark_op, print_result}; -pub fn benchmark_mapping(ns: &[usize]) +pub fn benchmark_mapping(rng: &mut StdRng, ns: &[usize]) where T: Mapping + Default + Clone, K: Copy, @@ -14,14 +15,14 @@ where Standard: Distribution + Distribution, { for n in ns { - scenario_populate::(*n); - scenario_contains::(*n); - scenario_remove::(*n); - scenario_clear::(*n); + scenario_populate::(rng, *n); + scenario_contains::(rng, *n); + scenario_remove::(rng, *n); + scenario_clear::(rng, *n); } } -fn scenario_populate(n: usize) +fn scenario_populate(rng: &mut StdRng, n: usize) where T: Mapping + Default + Clone, K: Copy, @@ -33,7 +34,7 @@ where ( T::default(), (0..n) - .map(|_| (random(), random())) + .map(|_| (rng.gen(), rng.gen())) .collect::>(), ) }, @@ -52,7 +53,7 @@ where print_result("insert", n, results); } -fn scenario_contains(n: usize) +fn scenario_contains(rng: &mut StdRng, n: usize) where T: Mapping + Default + Clone, K: Copy, @@ -61,7 +62,6 @@ where { let results = benchmark_op( || { - let mut rng = thread_rng(); let mut c = T::default(); // decide where the element that we will search for will be @@ -69,12 +69,12 @@ where // insert the element at pivot, and keep track of what it is for _ in 0..pivot { - c.insert(random(), random()); + c.insert(rng.gen(), rng.gen()); } let chosen = rng.gen(); - c.insert(chosen, random()); + c.insert(chosen, rng.gen()); for _ in pivot..n { - c.insert(random(), random()); + c.insert(rng.gen(), rng.gen()); } (c, chosen) @@ -85,7 +85,7 @@ where print_result("contains", n, results); } -fn scenario_remove(n: usize) +fn scenario_remove(rng: &mut StdRng, n: usize) where T: Mapping + Default + Clone, K: Copy, @@ -94,7 +94,6 @@ where { let results = benchmark_op( || { - let mut rng = thread_rng(); let mut c = T::default(); // decide where the element that we will search for will be @@ -102,12 +101,12 @@ where // insert the element at pivot, and keep track of what it is for _ in 0..pivot { - c.insert(random(), random()); + c.insert(rng.gen(), rng.gen()); } let chosen = rng.gen(); - c.insert(chosen, random()); + c.insert(chosen, rng.gen()); for _ in pivot..n { - c.insert(random(), random()); + c.insert(rng.gen(), rng.gen()); } (c, chosen) @@ -118,7 +117,7 @@ where print_result("remove", n, results); } -fn scenario_clear(n: usize) +fn scenario_clear(rng: &mut StdRng, n: usize) where T: Mapping + Default + Clone, K: Copy, @@ -130,7 +129,7 @@ where let mut c = T::default(); for _ in 0..n { - c.insert(random(), random()); + c.insert(rng.gen(), rng.gen()); } c }, diff --git a/src/crates/benchmarker/src/stack.rs b/src/crates/benchmarker/src/stack.rs index 93ba962..c5cf913 100644 --- a/src/crates/benchmarker/src/stack.rs +++ b/src/crates/benchmarker/src/stack.rs @@ -1,30 +1,30 @@ use std::hint::black_box; use primrose_library::traits::{Container, Stack}; -use rand::{distributions::Standard, prelude::Distribution, random}; +use rand::{distributions::Standard, prelude::Distribution, rngs::StdRng, Rng}; use crate::{benchmark_op, print_result}; -pub fn benchmark_stack(ns: &[usize]) +pub fn benchmark_stack(rng: &mut StdRng, ns: &[usize]) where T: Stack + Container + Default + Clone, E: Copy, Standard: Distribution, { for n in ns { - scenario_populate::(*n); - scenario_drain::(*n); + scenario_populate::(rng, *n); + scenario_drain::(rng, *n); } } -fn scenario_populate(n: usize) +fn scenario_populate(rng: &mut StdRng, n: usize) where T: Stack + Container + Default + Clone, E: Copy, Standard: Distribution, { let mut results = benchmark_op( - || (T::default(), (0..n).map(|_| random()).collect::>()), + || (T::default(), (0..n).map(|_| rng.gen()).collect::>()), |(c, xs)| { for x in xs { c.push(*x); @@ -40,7 +40,7 @@ where print_result("push", n, results); } -fn scenario_drain(n: usize) +fn scenario_drain(rng: &mut StdRng, n: usize) where T: Stack + Container + Default + Clone, E: Copy, @@ -50,7 +50,7 @@ where || { let mut c = T::default(); for _ in 0..n { - c.push(random()); + c.push(rng.gen()); } c }, diff --git a/src/crates/candelabra/src/cost/benchmark.rs b/src/crates/candelabra/src/cost/benchmark.rs index 79e2a16..885bc4a 100644 --- a/src/crates/candelabra/src/cost/benchmark.rs +++ b/src/crates/candelabra/src/cost/benchmark.rs @@ -25,9 +25,12 @@ pub const ELEM_TYPE: &str = "usize"; /// String representation of the array of N values we use for benchmarking pub const NS: &str = "[ - 64, 128, 256, 512, 2048, 5120, 16384, 32768, 65536, + 64, 256, 2048, 5120, 16384, 65536, 131072 ]"; +/// Fixed seed for benchmarking +pub const SEED: usize = 1337; + /// Results for a whole suite of benchmarks #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Results { @@ -201,7 +204,7 @@ primrose-library = {{ path = \"{}\" }} let implemented_traits = lib_spec.interface_provide_map.keys(); for tr in implemented_traits { benchmark_statements += &format!( - "candelabra_benchmarker::benchmark_{}::<{}<{}>, _>(&NS);", + "candelabra_benchmarker::benchmark_{}::<{}<{}>, _>(&mut rng, &NS);", tr.to_lowercase(), name, ELEM_TYPE, @@ -217,12 +220,13 @@ primrose-library = {{ path = \"{}\" }} .write_all( format!( " -const NS: &[usize] = &{}; +use candelabra_benchmarker::rand::{{rngs::StdRng, SeedableRng}}; +const NS: &[usize] = &{NS}; fn main() {{ - {} + let mut rng = StdRng::seed_from_u64({SEED}); + {benchmark_statements} }} ", - NS, benchmark_statements ) .as_bytes(), ) -- cgit v1.2.3