Skip to content

Commit bb6087f

Browse files
committed
feat: harden criterion compat library against optimization
1 parent ac7e208 commit bb6087f

File tree

1 file changed

+56
-47
lines changed

1 file changed

+56
-47
lines changed

crates/criterion_compat/src/compat/bencher.rs

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@ impl Bencher {
2525
R: FnMut() -> O,
2626
{
2727
let mut codspeed = self.codspeed.borrow_mut();
28-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
29-
black_box(routine());
28+
// NOTE: this structure hardens our benchmark against dead code elimination
29+
// https://godbolt.org/z/KnYeKMd1o
30+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
31+
if i < codspeed::codspeed::WARMUP_RUNS {
32+
black_box(routine());
33+
} else {
34+
codspeed.start_benchmark(self.uri.as_str());
35+
black_box(routine());
36+
codspeed.end_benchmark();
37+
}
3038
}
31-
codspeed.start_benchmark(self.uri.as_str());
32-
black_box(routine());
33-
codspeed.end_benchmark();
3439
}
3540

3641
#[inline(never)]
@@ -52,17 +57,20 @@ impl Bencher {
5257
R: FnMut(I) -> O,
5358
{
5459
let mut codspeed = self.codspeed.borrow_mut();
55-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
60+
61+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
5662
let input = black_box(setup());
57-
let output = routine(input);
63+
let output = if i < codspeed::codspeed::WARMUP_RUNS {
64+
black_box(routine(input))
65+
} else {
66+
let input = black_box(setup());
67+
codspeed.start_benchmark(self.uri.as_str());
68+
let output = black_box(routine(input));
69+
codspeed.end_benchmark();
70+
output
71+
};
5872
drop(black_box(output));
5973
}
60-
let input = black_box(setup());
61-
codspeed.start_benchmark(self.uri.as_str());
62-
let output = routine(input);
63-
codspeed.end_benchmark();
64-
65-
drop(black_box(output));
6674
}
6775

6876
pub fn iter_with_setup<I, O, S, R>(&mut self, setup: S, routine: R)
@@ -96,20 +104,19 @@ impl Bencher {
96104
{
97105
let mut codspeed = self.codspeed.borrow_mut();
98106

99-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
107+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
100108
let mut input = black_box(setup());
101-
let output = routine(&mut input);
109+
let output = if i < codspeed::codspeed::WARMUP_RUNS {
110+
black_box(routine(&mut input))
111+
} else {
112+
codspeed.start_benchmark(self.uri.as_str());
113+
let output = black_box(routine(&mut input));
114+
codspeed.end_benchmark();
115+
output
116+
};
102117
drop(black_box(output));
103118
drop(black_box(input));
104119
}
105-
106-
let mut input = black_box(setup());
107-
codspeed.start_benchmark(self.uri.as_str());
108-
let output = routine(&mut input);
109-
codspeed.end_benchmark();
110-
111-
drop(black_box(output));
112-
drop(black_box(input));
113120
}
114121

115122
#[cfg(feature = "async")]
@@ -136,14 +143,15 @@ impl<'b, A: AsyncExecutor> AsyncBencher<'b, A> {
136143
let AsyncBencher { b, runner } = self;
137144
runner.block_on(async {
138145
let mut codspeed = b.codspeed.borrow_mut();
139-
140-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
141-
black_box(routine().await);
146+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
147+
if i < codspeed::codspeed::WARMUP_RUNS {
148+
black_box(routine().await);
149+
} else {
150+
codspeed.start_benchmark(b.uri.as_str());
151+
black_box(routine().await);
152+
codspeed.end_benchmark();
153+
}
142154
}
143-
144-
codspeed.start_benchmark(b.uri.as_str());
145-
black_box(routine().await);
146-
codspeed.end_benchmark();
147155
});
148156
}
149157

@@ -201,17 +209,18 @@ impl<'b, A: AsyncExecutor> AsyncBencher<'b, A> {
201209
runner.block_on(async {
202210
let mut codspeed = b.codspeed.borrow_mut();
203211

204-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
212+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
205213
let input = black_box(setup());
206-
let output = routine(input).await;
214+
let output = if i < codspeed::codspeed::WARMUP_RUNS {
215+
black_box(routine(input).await)
216+
} else {
217+
codspeed.start_benchmark(b.uri.as_str());
218+
let output = black_box(routine(input).await);
219+
codspeed.end_benchmark();
220+
output
221+
};
207222
drop(black_box(output));
208223
}
209-
210-
let input = black_box(setup());
211-
codspeed.start_benchmark(b.uri.as_str());
212-
let output = routine(input).await;
213-
codspeed.end_benchmark();
214-
drop(black_box(output));
215224
})
216225
}
217226

@@ -231,19 +240,19 @@ impl<'b, A: AsyncExecutor> AsyncBencher<'b, A> {
231240
runner.block_on(async {
232241
let mut codspeed = b.codspeed.borrow_mut();
233242

234-
for _ in 0..codspeed::codspeed::WARMUP_RUNS {
243+
for i in 0..codspeed::codspeed::WARMUP_RUNS + 1 {
235244
let mut input = black_box(setup());
236-
let output = routine(&mut input).await;
245+
let output = if i < codspeed::codspeed::WARMUP_RUNS {
246+
black_box(routine(&mut input).await)
247+
} else {
248+
codspeed.start_benchmark(b.uri.as_str());
249+
let output = black_box(routine(&mut input).await);
250+
codspeed.end_benchmark();
251+
output
252+
};
237253
drop(black_box(output));
238254
drop(black_box(input));
239255
}
240-
241-
let mut input = black_box(setup());
242-
codspeed.start_benchmark(b.uri.as_str());
243-
let output = routine(&mut input).await;
244-
codspeed.end_benchmark();
245-
drop(black_box(output));
246-
drop(black_box(input));
247256
});
248257
}
249258
}

0 commit comments

Comments
 (0)