Skip to content

Commit 1f8a754

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 1f8a754

File tree

2 files changed

+33
-35
lines changed

2 files changed

+33
-35
lines changed

crates/criterion_compat/src/compat/bencher.rs

Lines changed: 29 additions & 32 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,36 +8,30 @@ 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();
3426
// NOTE: this structure hardens our benchmark against dead code elimination
3527
// https://godbolt.org/z/KnYeKMd1o
3628
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
3729
if i < codspeed::codspeed::WARMUP_RUNS {
3830
black_box(routine());
3931
} else {
40-
codspeed.start_benchmark(self.uri.as_str());
32+
self.codspeed.start_benchmark(self.uri.as_str());
4133
black_box(routine());
42-
codspeed.end_benchmark();
34+
self.codspeed.end_benchmark();
4335
}
4436
}
4537
}
@@ -62,17 +54,15 @@ impl<'a> Bencher<'a> {
6254
S: FnMut() -> I,
6355
R: FnMut(I) -> O,
6456
{
65-
let mut codspeed = self.codspeed.borrow_mut();
66-
6757
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
6858
let input = black_box(setup());
6959
let output = if i < codspeed::codspeed::WARMUP_RUNS {
7060
routine(input)
7161
} else {
7262
let input = black_box(setup());
73-
codspeed.start_benchmark(self.uri.as_str());
63+
self.codspeed.start_benchmark(self.uri.as_str());
7464
let output = routine(input);
75-
codspeed.end_benchmark();
65+
self.codspeed.end_benchmark();
7666
output
7767
};
7868
drop(black_box(output));
@@ -108,16 +98,14 @@ impl<'a> Bencher<'a> {
10898
S: FnMut() -> I,
10999
R: FnMut(&mut I) -> O,
110100
{
111-
let mut codspeed = self.codspeed.borrow_mut();
112-
113101
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
114102
let mut input = black_box(setup());
115103
let output = if i < codspeed::codspeed::WARMUP_RUNS {
116104
black_box(routine(&mut input))
117105
} else {
118-
codspeed.start_benchmark(self.uri.as_str());
106+
self.codspeed.start_benchmark(self.uri.as_str());
119107
let output = black_box(routine(&mut input));
120-
codspeed.end_benchmark();
108+
self.codspeed.end_benchmark();
121109
output
122110
};
123111
drop(black_box(output));
@@ -149,14 +137,13 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
149137
{
150138
let AsyncBencher { b, runner } = self;
151139
runner.block_on(async {
152-
let mut codspeed = b.codspeed.borrow_mut();
153140
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
154141
if i < codspeed::codspeed::WARMUP_RUNS {
155142
black_box(routine().await);
156143
} else {
157-
codspeed.start_benchmark(b.uri.as_str());
144+
b.codspeed.start_benchmark(b.uri.as_str());
158145
black_box(routine().await);
159-
codspeed.end_benchmark();
146+
b.codspeed.end_benchmark();
160147
}
161148
}
162149
});
@@ -214,16 +201,14 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
214201
{
215202
let AsyncBencher { b, runner } = self;
216203
runner.block_on(async {
217-
let mut codspeed = b.codspeed.borrow_mut();
218-
219204
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
220205
let input = black_box(setup());
221206
let output = if i < codspeed::codspeed::WARMUP_RUNS {
222207
routine(input).await
223208
} else {
224-
codspeed.start_benchmark(b.uri.as_str());
209+
b.codspeed.start_benchmark(b.uri.as_str());
225210
let output = routine(input).await;
226-
codspeed.end_benchmark();
211+
b.codspeed.end_benchmark();
227212
output
228213
};
229214
drop(black_box(output));
@@ -245,16 +230,14 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
245230
{
246231
let AsyncBencher { b, runner } = self;
247232
runner.block_on(async {
248-
let mut codspeed = b.codspeed.borrow_mut();
249-
250233
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
251234
let mut input = black_box(setup());
252235
let output = if i < codspeed::codspeed::WARMUP_RUNS {
253236
black_box(routine(&mut input).await)
254237
} else {
255-
codspeed.start_benchmark(b.uri.as_str());
238+
b.codspeed.start_benchmark(b.uri.as_str());
256239
let output = black_box(routine(&mut input).await);
257-
codspeed.end_benchmark();
240+
b.codspeed.end_benchmark();
258241
output
259242
};
260243
drop(black_box(output));
@@ -263,3 +246,17 @@ impl<'a, 'b, A: AsyncExecutor> AsyncBencher<'a, 'b, A> {
263246
});
264247
}
265248
}
249+
250+
#[cfg(test)]
251+
mod tests {
252+
use super::*;
253+
254+
fn assert_send<T: Send>() {}
255+
fn assert_sync<T: Sync>() {}
256+
257+
#[test]
258+
fn test_auto_traits() {
259+
assert_send::<Bencher>();
260+
assert_sync::<Bencher>();
261+
}
262+
}

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)