Skip to content

Commit ad60ffa

Browse files
committed
feat(criterion): make Bencher implement Send + Sync
`criterion`'s `Bencher` implements `Send + Sync`, which allows running the benchmark itself on another thread. This allows something like `|b| /* my rayon thread pool */.install(|| b.iter(|| /* bench */))`.
1 parent b211084 commit ad60ffa

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

crates/criterion_compat/src/compat/bencher.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::{cell::RefCell, rc::Rc};
2-
31
use codspeed::codspeed::{black_box, CodSpeed};
42
use colored::Colorize;
53
use criterion::BatchSize;
@@ -10,27 +8,22 @@ use criterion::async_executor::AsyncExecutor;
108
use std::future::Future;
119

1210
pub struct Bencher<'a> {
13-
codspeed: Rc<RefCell<CodSpeed>>,
11+
codspeed: &'a mut CodSpeed,
1412
uri: String,
15-
_marker: std::marker::PhantomData<&'a ()>,
1613
}
1714

1815
#[allow(clippy::needless_lifetimes)]
1916
impl<'a> Bencher<'a> {
20-
pub fn new(codspeed: Rc<RefCell<CodSpeed>>, uri: String) -> Self {
21-
Bencher {
22-
codspeed,
23-
uri,
24-
_marker: std::marker::PhantomData,
25-
}
17+
pub(crate) fn new(codspeed: &'a mut CodSpeed, uri: String) -> Self {
18+
Bencher { codspeed, uri }
2619
}
2720

2821
#[inline(never)]
2922
pub fn iter<O, R>(&mut self, mut routine: R)
3023
where
3124
R: FnMut() -> O,
3225
{
33-
let mut codspeed = self.codspeed.borrow_mut();
26+
let codspeed = &mut *self.codspeed;
3427
// NOTE: this structure hardens our benchmark against dead code elimination
3528
// https://godbolt.org/z/KnYeKMd1o
3629
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
@@ -62,7 +55,7 @@ impl<'a> Bencher<'a> {
6255
S: FnMut() -> I,
6356
R: FnMut(I) -> O,
6457
{
65-
let mut codspeed = self.codspeed.borrow_mut();
58+
let codspeed = &mut *self.codspeed;
6659

6760
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
6861
let input = black_box(setup());
@@ -108,7 +101,7 @@ impl<'a> Bencher<'a> {
108101
S: FnMut() -> I,
109102
R: FnMut(&mut I) -> O,
110103
{
111-
let mut codspeed = self.codspeed.borrow_mut();
104+
let codspeed = &mut *self.codspeed;
112105

113106
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
114107
let mut input = black_box(setup());
@@ -149,7 +142,7 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
149142
{
150143
let AsyncBencher { b, runner } = self;
151144
runner.block_on(async {
152-
let mut codspeed = b.codspeed.borrow_mut();
145+
let codspeed = &mut *b.codspeed;
153146
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
154147
if i < codspeed::codspeed::WARMUP_RUNS {
155148
black_box(routine().await);
@@ -214,7 +207,7 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
214207
{
215208
let AsyncBencher { b, runner } = self;
216209
runner.block_on(async {
217-
let mut codspeed = b.codspeed.borrow_mut();
210+
let codspeed = &mut *b.codspeed;
218211

219212
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
220213
let input = black_box(setup());
@@ -245,7 +238,7 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
245238
{
246239
let AsyncBencher { b, runner } = self;
247240
runner.block_on(async {
248-
let mut codspeed = b.codspeed.borrow_mut();
241+
let codspeed = &mut *b.codspeed;
249242

250243
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
251244
let mut input = black_box(setup());
@@ -263,3 +256,17 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
263256
});
264257
}
265258
}
259+
260+
#[cfg(test)]
261+
mod tests {
262+
use super::*;
263+
264+
fn assert_send<T: Send>() {}
265+
fn assert_sync<T: Sync>() {}
266+
267+
#[test]
268+
fn test_auto_traits() {
269+
assert_send::<Bencher>();
270+
assert_sync::<Bencher>();
271+
}
272+
}

crates/criterion_compat/src/compat/group.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub struct BenchmarkGroup<'a, M: Measurement = WallTime> {
1919

2020
#[allow(clippy::needless_lifetimes)]
2121
impl<'a, M: Measurement> BenchmarkGroup<'a, M> {
22-
pub fn new(criterion: &mut Criterion<M>, group_name: String) -> BenchmarkGroup<M> {
23-
BenchmarkGroup::<M> {
22+
pub(crate) fn new(criterion: &'a mut Criterion<M>, group_name: String) -> Self {
23+
Self {
2424
codspeed: criterion
2525
.codspeed
2626
.as_ref()
@@ -73,7 +73,8 @@ impl<'a, M: Measurement> BenchmarkGroup<'a, M> {
7373
if let Some(parameter) = id.parameter {
7474
uri = format!("{uri}[{parameter}]");
7575
}
76-
let mut b = Bencher::new(self.codspeed.clone(), uri);
76+
let mut codspeed = self.codspeed.borrow_mut();
77+
let mut b = Bencher::new(&mut codspeed, uri);
7778
f(&mut b, input);
7879
}
7980
}

0 commit comments

Comments
 (0)