1 use criterion::{
2 criterion_group, criterion_main, Bencher, Criterion, Throughput,
3 };
4
5 mod data;
6 mod memchr;
7 mod memmem;
8
all(c: &mut Criterion)9 fn all(c: &mut Criterion) {
10 memchr::all(c);
11 memmem::all(c);
12 }
13
14 /// A convenience function for defining a Criterion benchmark using our own
15 /// conventions and a common config.
16 ///
17 /// Note that we accept `bench` as a boxed closure to avoid the costs
18 /// of monomorphization. Particularly with the memchr benchmarks, this
19 /// function getting monomorphized (which also monomorphizes via Criterion's
20 /// `bench_function`) bloats compile times dramatically (by an order of
21 /// magnitude). This is okay to do since `bench` isn't the actual thing we
22 /// measure. The measurement comes from running `Bencher::iter` from within`
23 /// bench. So the dynamic dispatch is okay here.
define( c: &mut Criterion, name: &str, corpus: &[u8], bench: Box<dyn FnMut(&mut Bencher<'_>) + 'static>, )24 fn define(
25 c: &mut Criterion,
26 name: &str,
27 corpus: &[u8],
28 bench: Box<dyn FnMut(&mut Bencher<'_>) + 'static>,
29 ) {
30 // I don't really "get" the whole Criterion benchmark group thing. I just
31 // want a flat namespace to define all benchmarks. The only thing that
32 // matters to me is that we can group benchmarks arbitrarily using the
33 // name only. So we play Criterion's game by splitting our benchmark name
34 // on the first flash.
35 //
36 // N.B. We don't include the slash, since Criterion automatically adds it.
37 let mut it = name.splitn(2, "/");
38 let (group_name, bench_name) = (it.next().unwrap(), it.next().unwrap());
39 c.benchmark_group(group_name)
40 .throughput(Throughput::Bytes(corpus.len() as u64))
41 .sample_size(10)
42 .warm_up_time(std::time::Duration::from_millis(500))
43 .measurement_time(std::time::Duration::from_secs(2))
44 .bench_function(bench_name, bench);
45 }
46
47 criterion_group!(does_not_matter, all);
48 criterion_main!(does_not_matter);
49