Skip to content

Commit 110a0aa

Browse files
Add macro bench_specializations
1 parent 6710e71 commit 110a0aa

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,7 @@ harness = false
7171
[[bench]]
7272
name = "powerset"
7373
harness = false
74+
75+
[[bench]]
76+
name = "specializations"
77+
harness = false

benches/specializations.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use criterion::black_box;
2+
use itertools::Itertools;
3+
4+
/// Create multiple functions each defining a benchmark group about iterator methods.
5+
///
6+
/// Each created group has functions with the following ids:
7+
///
8+
/// - `next`, `size_hint`, `count`, `last`, `nth`, `collect`, `fold`
9+
/// - and when marked as `DoubleEndedIterator`: `next_back`, `rfold`
10+
/// - and when marked as `ExactSizeIterator`: `len`
11+
///
12+
/// Note that this macro can be called only once.
13+
macro_rules! bench_specializations {
14+
(
15+
$(
16+
$name:ident {
17+
$($extra:ident)*
18+
{$(
19+
$init:stmt;
20+
)*}
21+
$iterator:expr
22+
}
23+
)*
24+
) => {
25+
$(
26+
fn $name(c: &mut ::criterion::Criterion) {
27+
let mut bench_group = c.benchmark_group(stringify!($name));
28+
$(
29+
$init
30+
)*
31+
let bench_first_its = {
32+
let mut bench_idx = 0;
33+
[0; 1000].map(|_| {
34+
let mut it = $iterator;
35+
if bench_idx != 0 {
36+
it.nth(bench_idx - 1);
37+
}
38+
bench_idx += 1;
39+
it
40+
})
41+
};
42+
bench_specializations!(@Iterator bench_group bench_first_its: $iterator);
43+
$(
44+
bench_specializations!(@$extra bench_group bench_first_its: $iterator);
45+
)*
46+
bench_group.finish();
47+
}
48+
)*
49+
50+
::criterion::criterion_group!(benches, $($name, )*);
51+
::criterion::criterion_main!(benches);
52+
};
53+
54+
(@Iterator $group:ident $first_its:ident: $iterator:expr) => {
55+
$group.bench_function("next", |bencher| bencher.iter(|| {
56+
let mut it = $iterator;
57+
while let Some(x) = it.next() {
58+
black_box(x);
59+
}
60+
}));
61+
$group.bench_function("size_hint", |bencher| bencher.iter(|| {
62+
$first_its.iter().for_each(|it| {
63+
black_box(it.size_hint());
64+
})
65+
}));
66+
$group.bench_function("count", |bencher| bencher.iter(|| {
67+
$iterator.count()
68+
}));
69+
$group.bench_function("last", |bencher| bencher.iter(|| {
70+
$iterator.last()
71+
}));
72+
$group.bench_function("nth", |bencher| bencher.iter(|| {
73+
for start in 0_usize..10 {
74+
for n in 0..10 {
75+
let mut it = $iterator;
76+
if let Some(s) = start.checked_sub(1) {
77+
black_box(it.nth(s));
78+
}
79+
while let Some(x) = it.nth(n) {
80+
black_box(x);
81+
}
82+
}
83+
}
84+
}));
85+
$group.bench_function("collect", |bencher| bencher.iter(|| {
86+
$iterator.collect::<Vec<_>>()
87+
}));
88+
$group.bench_function("fold", |bencher| bencher.iter(|| {
89+
$iterator.fold((), |(), x| {
90+
black_box(x);
91+
})
92+
}));
93+
};
94+
95+
(@DoubleEndedIterator $group:ident $_first_its:ident: $iterator:expr) => {
96+
$group.bench_function("next_back", |bencher| bencher.iter(|| {
97+
let mut it = $iterator;
98+
while let Some(x) = it.next_back() {
99+
black_box(x);
100+
}
101+
}));
102+
$group.bench_function("rfold", |bencher| bencher.iter(|| {
103+
$iterator.rfold((), |(), x| {
104+
black_box(x);
105+
})
106+
}));
107+
};
108+
109+
(@ExactSizeIterator $group:ident $first_its:ident: $_iterator:expr) => {
110+
$group.bench_function("len", |bencher| bencher.iter(|| {
111+
$first_its.iter().for_each(|it| {
112+
black_box(it.len());
113+
})
114+
}));
115+
};
116+
}
117+
118+
// Example: To bench only `ZipLongest::fold`, you can do
119+
// cargo bench --bench specializations zip_longest/fold
120+
bench_specializations! {
121+
zip_longest {
122+
DoubleEndedIterator
123+
ExactSizeIterator
124+
{
125+
let xs = black_box(vec![0; 1024]);
126+
let ys = black_box(vec![0; 768]);
127+
}
128+
xs.iter().zip_longest(ys.iter())
129+
}
130+
}

0 commit comments

Comments
 (0)