pub struct BenchGroup { /* private fields */ }Expand description
A group of benchmarks to compare via interleaved execution.
Implementations§
Source§impl BenchGroup
impl BenchGroup
Sourcepub fn new_public(name: impl Into<String>) -> Self
pub fn new_public(name: impl Into<String>) -> Self
Create a new group (public, for criterion_compat).
Sourcepub fn bench<F>(&mut self, name: impl Into<String>, f: F)
pub fn bench<F>(&mut self, name: impl Into<String>, f: F)
Add a benchmark to this comparison group.
Sourcepub fn bench_tagged<F>(
&mut self,
name: impl Into<String>,
tags: &[(&str, &str)],
f: F,
)
pub fn bench_tagged<F>( &mut self, name: impl Into<String>, tags: &[(&str, &str)], f: F, )
Add a benchmark with key-value tags for multi-dimensional reporting.
Tags enable grouping and pivoting in reports. Common tags:
("library", "zenflate"), ("level", "L6"), ("data", "mixed").
Sourcepub fn bench_contended<S, Setup, Work>(
&mut self,
name: impl Into<String>,
threads: usize,
setup: Setup,
work: Work,
)
pub fn bench_contended<S, Setup, Work>( &mut self, name: impl Into<String>, threads: usize, setup: Setup, work: Work, )
Add a multithreaded contention benchmark.
Spawns threads threads that all start simultaneously (barrier-synchronized)
and run the benchmark closure in parallel. Measures wall-clock time from
barrier release to all threads completing — this is the throughput under
contention that your users experience.
The setup closure runs once to create shared state (typically an Arc).
The work closure runs on each thread with a reference to the shared state
and the thread index (0..threads).
group.bench_contended("mutex_map", 8,
|| Arc::new(Mutex::new(HashMap::new())),
|b, shared, thread_id| {
b.iter(|| { shared.lock().unwrap().insert(thread_id, 42); })
},
);Sourcepub fn bench_parallel<F>(
&mut self,
name: impl Into<String>,
threads: usize,
work: F,
)
pub fn bench_parallel<F>( &mut self, name: impl Into<String>, threads: usize, work: F, )
Add a parallel throughput benchmark (no shared state).
Spawns threads threads that each run the same work independently.
Measures total wall-clock time. Use this to find scaling limits —
if 4 threads aren’t 4x faster, you’re hitting cache/memory bandwidth
or SMT contention.
Each thread gets its own thread index (0..threads) but no shared state.
For shared-state contention testing, use BenchGroup::bench_contended instead.
// Compare 1, 2, 4 threads doing independent work
for threads in [1, 2, 4] {
group.bench_parallel(format!("{threads}t"), threads, |b, _tid| {
b.iter(|| std::hint::black_box(42u64.wrapping_mul(7)))
});
}Rayon / existing thread pools: Don’t use this for code that manages
its own threads (rayon, tokio, etc.). Just use regular bench() —
wall-clock timing already captures all threads’ work. bench_parallel
spawns its own threads, which would compete with rayon’s pool.
Sourcepub fn bench_scaling<F>(&mut self, name: impl Into<String>, work: F)
pub fn bench_scaling<F>(&mut self, name: impl Into<String>, work: F)
Automatic thread scaling analysis.
Probes thread counts from 1 up to the system’s logical core count (powers of 2 plus the physical core count). Each thread count becomes a separate benchmark in the group, interleaved and compared.
Use with Throughput::Elements(N) to see scaling and efficiency:
group.throughput(Throughput::Elements(10_000));
group.bench_scaling("sqrt_work", |b, _tid| {
b.iter(|| std::hint::black_box(42u64.wrapping_mul(7)))
});The 1-thread benchmark is the baseline. The report shows how throughput scales (or doesn’t) with more threads.
Sourcepub fn throughput(&mut self, throughput: Throughput) -> &mut Self
pub fn throughput(&mut self, throughput: Throughput) -> &mut Self
Declare the throughput for this group.
All benchmarks in the group process the same amount of data, so throughput is set at the group level.
Sourcepub fn subgroup(&mut self, label: impl Into<String>) -> &mut Self
pub fn subgroup(&mut self, label: impl Into<String>) -> &mut Self
Set a visual subgroup label for subsequent benchmarks.
Subgroups are display-only — benchmarks are still interleaved and compared across subgroups within the same comparison group. The label appears as a section header in the table and bar chart.
group.subgroup("Ok path");
group.bench("no_error", |b| b.iter(|| std::hint::black_box(1)));
group.subgroup("Error path");
group.bench("with_backtrace", |b| b.iter(|| std::hint::black_box(2)));Sourcepub fn throughput_unit(&mut self, unit: impl Into<String>) -> &mut Self
pub fn throughput_unit(&mut self, unit: impl Into<String>) -> &mut Self
Set a custom unit name for Throughput::Elements.
When set, reports show e.g. “5.0 Gchecks/s” instead of “5.0 Gops/s”.
Sourcepub fn baseline(&mut self, name: impl Into<String>) -> &mut Self
pub fn baseline(&mut self, name: impl Into<String>) -> &mut Self
Set which benchmark is the baseline for comparisons.
By default, the first benchmark added is the baseline. Use this to compare against a different benchmark by name.
Sourcepub fn config(&mut self) -> &mut GroupConfig
pub fn config(&mut self) -> &mut GroupConfig
Configure this group’s execution parameters.