From fbb5cf944da64e8c69797f1e3511dddeb8f8b5f4 Mon Sep 17 00:00:00 2001 From: Thomas Korrison Date: Mon, 27 Apr 2026 21:05:12 +0100 Subject: [PATCH] refactor: optimize value pool allocation in benchmarks - Replaced `build_value_pool` with `preallocate_values` to pre-allocate `Arc` instances for each key in the universe. - This change reduces allocation overhead during benchmark runs, isolating policy behavior from allocator variance by only incurring the cost of `Arc::clone` per insert. - Updated benchmark functions to utilize the new preallocation method, enhancing performance measurement accuracy. These modifications improve the efficiency of benchmark tests and ensure more reliable performance metrics. --- benches/workloads.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/benches/workloads.rs b/benches/workloads.rs index b0f387b..1b2f99f 100644 --- a/benches/workloads.rs +++ b/benches/workloads.rs @@ -56,11 +56,14 @@ fn make_generator(workload: Workload) -> WorkloadGenerator { .generator() } -/// Pre-built `Arc` per key in `0..universe`. Sharing one pool across all -/// benchmark iterations keeps `Arc::new` out of the timed region so we measure -/// policy behavior rather than allocator latency. -fn build_value_pool(universe: u64) -> Arc<[Arc]> { - (0..universe).map(Arc::new).collect::>().into() +/// Pre-allocate one `Arc` per key in the universe. +/// +/// Reused across policies and workloads so the measured loop only pays the +/// cost of an `Arc::clone` (atomic refcount bump) per insert rather than a +/// fresh heap allocation. This isolates policy hit/miss/eviction behavior +/// from allocator variance. +fn preallocate_values() -> Vec> { + (0..UNIVERSE).map(Arc::new).collect() } // ============================================================================ @@ -70,7 +73,7 @@ fn build_value_pool(universe: u64) -> Arc<[Arc]> { fn bench_hit_rates(c: &mut Criterion) { let mut group = c.benchmark_group("hit_rate"); group.throughput(Throughput::Elements(OPS as u64)); - let value_pool = build_value_pool(UNIVERSE); + let value_pool = preallocate_values(); for workload_case in STANDARD_WORKLOADS { let workload = workload_case.workload; @@ -181,7 +184,7 @@ fn bench_adaptation_speed(c: &mut Criterion) { fn bench_comprehensive(c: &mut Criterion) { let mut group = c.benchmark_group("comprehensive"); - let value_pool = build_value_pool(UNIVERSE); + let value_pool = preallocate_values(); for workload_case in STANDARD_WORKLOADS { let config = BenchmarkConfig {