From 4df7574db5a793dd0d9ff2f65441a776da0764f8 Mon Sep 17 00:00:00 2001 From: Andreas Liljeqvist Date: Mon, 19 Jan 2026 21:50:10 +0100 Subject: [PATCH] perf: reduce benchmark suite runtime from 8min to 35s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add size-based timing configuration to benchmarks: - Small inputs (≤64 bytes): 100ms warmup, 200ms measurement - Medium inputs (65-512 bytes): 100ms warmup, 300ms measurement - Large inputs (>512 bytes): 200ms warmup, 500ms measurement Also reduce nresamples from 100k to 10k for faster bootstrap analysis. Variance testing shows <5% CV for most benchmarks, with ASCII fast path achieving <1% CV. Total runtime is consistent at ~35s (0.3% CV). --- benches/benchmarks.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 84bd9e7..1fda971 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -1,4 +1,9 @@ -use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use std::time::Duration; + +use criterion::{ + criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, BenchmarkId, Criterion, + Throughput, +}; use rand::distributions::uniform::SampleRange; use rand::distributions::{Distribution, WeightedIndex}; @@ -7,6 +12,19 @@ use rand_pcg::{Lcg128Xsl64, Pcg64}; use yore::code_pages::CP874; +/// Configure benchmark timing based on input size. +/// Smaller inputs need less time since they run many more iterations. +fn configure_for_size(group: &mut BenchmarkGroup, size: usize) { + let (warm_up_ms, measurement_ms) = match size { + 0..=64 => (100, 200), + 65..=512 => (100, 300), + _ => (200, 500), + }; + group + .warm_up_time(Duration::from_millis(warm_up_ms)) + .measurement_time(Duration::from_millis(measurement_ms)); +} + fn encode_checked( c: &mut Criterion, label: &str, @@ -16,6 +34,7 @@ fn encode_checked( let mut group = c.benchmark_group(label); let mut rng_yore = Pcg64::seed_from_u64(42); for size in sizes { + configure_for_size(&mut group, *size); group .throughput(Throughput::Bytes(*size as u64)) .bench_with_input(BenchmarkId::from_parameter(size), size, |b, size| { @@ -35,6 +54,7 @@ fn encode_lossy( let mut group = c.benchmark_group(label); let mut rng_yore = Pcg64::seed_from_u64(42); for size in sizes { + configure_for_size(&mut group, *size); group .throughput(Throughput::Bytes(*size as u64)) .bench_with_input(BenchmarkId::from_parameter(size), size, |b, size| { @@ -54,6 +74,7 @@ fn decode_checked( let mut rng_yore = Pcg64::seed_from_u64(42); let mut group = c.benchmark_group(label); for size in sizes { + configure_for_size(&mut group, *size); group .throughput(Throughput::Bytes(*size as u64)) .bench_with_input(BenchmarkId::from_parameter(size), size, |b, size| { @@ -73,6 +94,7 @@ fn decode_lossy( let mut rng_yore = Pcg64::seed_from_u64(42); let mut group = c.benchmark_group(label); for size in sizes { + configure_for_size(&mut group, *size); group .throughput(Throughput::Bytes(*size as u64)) .bench_with_input(BenchmarkId::from_parameter(size), size, |b, size| { @@ -155,5 +177,9 @@ fn bench(c: &mut Criterion) { encode_lossy(c, "encode_lossy/all_bad", sizes, all_bad_strings); } -criterion_group!(benches, bench); +criterion_group! { + name = benches; + config = Criterion::default().nresamples(10_000); + targets = bench +} criterion_main!(benches);