]> git.proxmox.com Git - rustc.git/blame - library/core/benches/iter.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / library / core / benches / iter.rs
CommitLineData
8bb4bdeb 1use core::iter::*;
60c5eb7d 2use test::{black_box, Bencher};
8bb4bdeb
XL
3
4#[bench]
5fn bench_rposition(b: &mut Bencher) {
6 let it: Vec<usize> = (0..300).collect();
7 b.iter(|| {
8 it.iter().rposition(|&x| x <= 150);
9 });
10}
11
12#[bench]
13fn bench_skip_while(b: &mut Bencher) {
14 b.iter(|| {
15 let it = 0..100;
16 let mut sum = 0;
60c5eb7d
XL
17 it.skip_while(|&x| {
18 sum += x;
19 sum < 4000
20 })
21 .all(|_| true);
8bb4bdeb
XL
22 });
23}
24
25#[bench]
26fn bench_multiple_take(b: &mut Bencher) {
27 let mut it = (0..42).cycle();
28 b.iter(|| {
29 let n = it.next().unwrap();
30 for _ in 0..n {
31 it.clone().take(it.next().unwrap()).all(|_| true);
32 }
33 });
34}
35
60c5eb7d
XL
36fn scatter(x: i32) -> i32 {
37 (x * 31) % 127
38}
8bb4bdeb
XL
39
40#[bench]
41fn bench_max_by_key(b: &mut Bencher) {
42 b.iter(|| {
43 let it = 0..100;
532ac7d7 44 it.map(black_box).max_by_key(|&x| scatter(x))
8bb4bdeb
XL
45 })
46}
47
136023e0 48// https://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
8bb4bdeb
XL
49#[bench]
50fn bench_max_by_key2(b: &mut Bencher) {
51 fn max_index_iter(array: &[i32]) -> usize {
52 array.iter().enumerate().max_by_key(|&(_, item)| item).unwrap().0
53 }
54
55 let mut data = vec![0; 1638];
56 data[514] = 9999;
57
58 b.iter(|| max_index_iter(&data));
59}
60
61#[bench]
62fn bench_max(b: &mut Bencher) {
63 b.iter(|| {
64 let it = 0..100;
532ac7d7 65 it.map(black_box).map(scatter).max()
8bb4bdeb
XL
66 })
67}
68
69pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
70 for (a, b) in ys.iter_mut().zip(xs) {
71 *a = *b;
72 }
73}
74
75pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
76 for (a, b) in ys.iter_mut().zip(xs) {
77 *a += *b;
78 }
79}
80
81#[bench]
82fn bench_zip_copy(b: &mut Bencher) {
83 let source = vec![0u8; 16 * 1024];
84 let mut dst = black_box(vec![0u8; 16 * 1024]);
60c5eb7d 85 b.iter(|| copy_zip(&source, &mut dst))
8bb4bdeb
XL
86}
87
88#[bench]
89fn bench_zip_add(b: &mut Bencher) {
90 let source = vec![1.; 16 * 1024];
91 let mut dst = vec![0.; 16 * 1024];
60c5eb7d 92 b.iter(|| add_zip(&source, &mut dst));
8bb4bdeb 93}
041b39d2
XL
94
95/// `Iterator::for_each` implemented as a plain loop.
60c5eb7d
XL
96fn for_each_loop<I, F>(iter: I, mut f: F)
97where
98 I: Iterator,
99 F: FnMut(I::Item),
041b39d2
XL
100{
101 for item in iter {
102 f(item);
103 }
104}
105
106/// `Iterator::for_each` implemented with `fold` for internal iteration.
107/// (except when `by_ref()` effectively disables that optimization.)
60c5eb7d
XL
108fn for_each_fold<I, F>(iter: I, mut f: F)
109where
110 I: Iterator,
111 F: FnMut(I::Item),
041b39d2
XL
112{
113 iter.fold((), move |(), item| f(item));
114}
115
116#[bench]
117fn bench_for_each_chain_loop(b: &mut Bencher) {
118 b.iter(|| {
119 let mut acc = 0;
120 let iter = (0i64..1000000).chain(0..1000000).map(black_box);
121 for_each_loop(iter, |x| acc += x);
122 acc
123 });
124}
125
126#[bench]
127fn bench_for_each_chain_fold(b: &mut Bencher) {
128 b.iter(|| {
129 let mut acc = 0;
130 let iter = (0i64..1000000).chain(0..1000000).map(black_box);
131 for_each_fold(iter, |x| acc += x);
132 acc
133 });
134}
135
136#[bench]
137fn bench_for_each_chain_ref_fold(b: &mut Bencher) {
138 b.iter(|| {
139 let mut acc = 0;
140 let mut iter = (0i64..1000000).chain(0..1000000).map(black_box);
141 for_each_fold(iter.by_ref(), |x| acc += x);
142 acc
143 });
144}
ea8adc8c 145
ea8adc8c
XL
146/// Helper to benchmark `sum` for iterators taken by value which
147/// can optimize `fold`, and by reference which cannot.
148macro_rules! bench_sums {
149 ($bench_sum:ident, $bench_ref_sum:ident, $iter:expr) => {
150 #[bench]
151 fn $bench_sum(b: &mut Bencher) {
60c5eb7d 152 b.iter(|| -> i64 { $iter.map(black_box).sum() });
ea8adc8c
XL
153 }
154
155 #[bench]
156 fn $bench_ref_sum(b: &mut Bencher) {
60c5eb7d 157 b.iter(|| -> i64 { $iter.map(black_box).by_ref().sum() });
ea8adc8c 158 }
60c5eb7d 159 };
ea8adc8c
XL
160}
161
162bench_sums! {
163 bench_flat_map_sum,
164 bench_flat_map_ref_sum,
165 (0i64..1000).flat_map(|x| x..x+1000)
166}
167
168bench_sums! {
169 bench_flat_map_chain_sum,
170 bench_flat_map_chain_ref_sum,
171 (0i64..1000000).flat_map(|x| once(x).chain(once(x)))
172}
173
174bench_sums! {
175 bench_enumerate_sum,
176 bench_enumerate_ref_sum,
177 (0i64..1000000).enumerate().map(|(i, x)| x * i as i64)
178}
179
180bench_sums! {
181 bench_enumerate_chain_sum,
182 bench_enumerate_chain_ref_sum,
183 (0i64..1000000).chain(0..1000000).enumerate().map(|(i, x)| x * i as i64)
184}
185
186bench_sums! {
187 bench_filter_sum,
188 bench_filter_ref_sum,
532ac7d7 189 (0i64..1000000).filter(|x| x % 3 == 0)
ea8adc8c
XL
190}
191
192bench_sums! {
193 bench_filter_chain_sum,
194 bench_filter_chain_ref_sum,
532ac7d7 195 (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0)
ea8adc8c
XL
196}
197
198bench_sums! {
199 bench_filter_map_sum,
200 bench_filter_map_ref_sum,
201 (0i64..1000000).filter_map(|x| x.checked_mul(x))
202}
203
204bench_sums! {
205 bench_filter_map_chain_sum,
206 bench_filter_map_chain_ref_sum,
207 (0i64..1000000).chain(0..1000000).filter_map(|x| x.checked_mul(x))
208}
209
210bench_sums! {
211 bench_fuse_sum,
212 bench_fuse_ref_sum,
213 (0i64..1000000).fuse()
214}
215
216bench_sums! {
217 bench_fuse_chain_sum,
218 bench_fuse_chain_ref_sum,
219 (0i64..1000000).chain(0..1000000).fuse()
220}
221
222bench_sums! {
223 bench_inspect_sum,
224 bench_inspect_ref_sum,
225 (0i64..1000000).inspect(|_| {})
226}
227
228bench_sums! {
229 bench_inspect_chain_sum,
230 bench_inspect_chain_ref_sum,
231 (0i64..1000000).chain(0..1000000).inspect(|_| {})
232}
233
234bench_sums! {
235 bench_peekable_sum,
236 bench_peekable_ref_sum,
237 (0i64..1000000).peekable()
238}
239
240bench_sums! {
241 bench_peekable_chain_sum,
242 bench_peekable_chain_ref_sum,
243 (0i64..1000000).chain(0..1000000).peekable()
244}
245
246bench_sums! {
247 bench_skip_sum,
248 bench_skip_ref_sum,
249 (0i64..1000000).skip(1000)
250}
251
252bench_sums! {
253 bench_skip_chain_sum,
254 bench_skip_chain_ref_sum,
255 (0i64..1000000).chain(0..1000000).skip(1000)
256}
257
258bench_sums! {
259 bench_skip_while_sum,
260 bench_skip_while_ref_sum,
261 (0i64..1000000).skip_while(|&x| x < 1000)
262}
263
264bench_sums! {
265 bench_skip_while_chain_sum,
266 bench_skip_while_chain_ref_sum,
267 (0i64..1000000).chain(0..1000000).skip_while(|&x| x < 1000)
268}
abe05a73
XL
269
270bench_sums! {
271 bench_take_while_chain_sum,
272 bench_take_while_chain_ref_sum,
273 (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111)
274}
0531ce1d 275
0731742a
XL
276bench_sums! {
277 bench_cycle_take_sum,
278 bench_cycle_take_ref_sum,
5869c6ff
XL
279 (0..10000).cycle().take(1000000)
280}
281
282bench_sums! {
283 bench_cycle_skip_take_sum,
284 bench_cycle_skip_take_ref_sum,
285 (0..100000).cycle().skip(1000000).take(1000000)
286}
287
288bench_sums! {
289 bench_cycle_take_skip_sum,
290 bench_cycle_take_skip_ref_sum,
291 (0..100000).cycle().take(1000000).skip(100000)
292}
293
294bench_sums! {
295 bench_skip_cycle_skip_zip_add_sum,
296 bench_skip_cycle_skip_zip_add_ref_sum,
297 (0..100000).skip(100).cycle().skip(100)
298 .zip((0..100000).cycle().skip(10))
299 .map(|(a,b)| a+b)
300 .skip(100000)
301 .take(1000000)
0731742a
XL
302}
303
0531ce1d
XL
304// Checks whether Skip<Zip<A,B>> is as fast as Zip<Skip<A>, Skip<B>>, from
305// https://users.rust-lang.org/t/performance-difference-between-iterator-zip-and-skip-order/15743
306#[bench]
307fn bench_zip_then_skip(b: &mut Bencher) {
308 let v: Vec<_> = (0..100_000).collect();
309 let t: Vec<_> = (0..100_000).collect();
310
311 b.iter(|| {
60c5eb7d
XL
312 let s = v
313 .iter()
314 .zip(t.iter())
315 .skip(10000)
0531ce1d
XL
316 .take_while(|t| *t.0 < 10100)
317 .map(|(a, b)| *a + *b)
318 .sum::<u64>();
319 assert_eq!(s, 2009900);
320 });
321}
322#[bench]
323fn bench_skip_then_zip(b: &mut Bencher) {
324 let v: Vec<_> = (0..100_000).collect();
325 let t: Vec<_> = (0..100_000).collect();
326
327 b.iter(|| {
60c5eb7d
XL
328 let s = v
329 .iter()
330 .skip(10000)
331 .zip(t.iter().skip(10000))
0531ce1d
XL
332 .take_while(|t| *t.0 < 10100)
333 .map(|(a, b)| *a + *b)
334 .sum::<u64>();
335 assert_eq!(s, 2009900);
336 });
337}
532ac7d7
XL
338
339#[bench]
340fn bench_filter_count(b: &mut Bencher) {
60c5eb7d 341 b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())
532ac7d7
XL
342}
343
344#[bench]
345fn bench_filter_ref_count(b: &mut Bencher) {
60c5eb7d 346 b.iter(|| (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count())
532ac7d7
XL
347}
348
349#[bench]
350fn bench_filter_chain_count(b: &mut Bencher) {
60c5eb7d 351 b.iter(|| (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count())
532ac7d7
XL
352}
353
354#[bench]
355fn bench_filter_chain_ref_count(b: &mut Bencher) {
356 b.iter(|| {
357 (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
358 })
359}
360
361#[bench]
362fn bench_partial_cmp(b: &mut Bencher) {
363 b.iter(|| (0..100000).map(black_box).partial_cmp((0..100000).map(black_box)))
364}
365
366#[bench]
367fn bench_lt(b: &mut Bencher) {
368 b.iter(|| (0..100000).map(black_box).lt((0..100000).map(black_box)))
369}