]> git.proxmox.com Git - rustc.git/blob - src/libcore/benches/iter.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / libcore / benches / iter.rs
1 use core::iter::*;
2 use test::{black_box, Bencher};
3
4 #[bench]
5 fn 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]
13 fn bench_skip_while(b: &mut Bencher) {
14 b.iter(|| {
15 let it = 0..100;
16 let mut sum = 0;
17 it.skip_while(|&x| {
18 sum += x;
19 sum < 4000
20 })
21 .all(|_| true);
22 });
23 }
24
25 #[bench]
26 fn 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
36 fn scatter(x: i32) -> i32 {
37 (x * 31) % 127
38 }
39
40 #[bench]
41 fn bench_max_by_key(b: &mut Bencher) {
42 b.iter(|| {
43 let it = 0..100;
44 it.map(black_box).max_by_key(|&x| scatter(x))
45 })
46 }
47
48 // http://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
49 #[bench]
50 fn 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]
62 fn bench_max(b: &mut Bencher) {
63 b.iter(|| {
64 let it = 0..100;
65 it.map(black_box).map(scatter).max()
66 })
67 }
68
69 pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
70 for (a, b) in ys.iter_mut().zip(xs) {
71 *a = *b;
72 }
73 }
74
75 pub 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]
82 fn bench_zip_copy(b: &mut Bencher) {
83 let source = vec![0u8; 16 * 1024];
84 let mut dst = black_box(vec![0u8; 16 * 1024]);
85 b.iter(|| copy_zip(&source, &mut dst))
86 }
87
88 #[bench]
89 fn bench_zip_add(b: &mut Bencher) {
90 let source = vec![1.; 16 * 1024];
91 let mut dst = vec![0.; 16 * 1024];
92 b.iter(|| add_zip(&source, &mut dst));
93 }
94
95 /// `Iterator::for_each` implemented as a plain loop.
96 fn for_each_loop<I, F>(iter: I, mut f: F)
97 where
98 I: Iterator,
99 F: FnMut(I::Item),
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.)
108 fn for_each_fold<I, F>(iter: I, mut f: F)
109 where
110 I: Iterator,
111 F: FnMut(I::Item),
112 {
113 iter.fold((), move |(), item| f(item));
114 }
115
116 #[bench]
117 fn 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]
127 fn 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]
137 fn 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 }
145
146 /// Helper to benchmark `sum` for iterators taken by value which
147 /// can optimize `fold`, and by reference which cannot.
148 macro_rules! bench_sums {
149 ($bench_sum:ident, $bench_ref_sum:ident, $iter:expr) => {
150 #[bench]
151 fn $bench_sum(b: &mut Bencher) {
152 b.iter(|| -> i64 { $iter.map(black_box).sum() });
153 }
154
155 #[bench]
156 fn $bench_ref_sum(b: &mut Bencher) {
157 b.iter(|| -> i64 { $iter.map(black_box).by_ref().sum() });
158 }
159 };
160 }
161
162 bench_sums! {
163 bench_flat_map_sum,
164 bench_flat_map_ref_sum,
165 (0i64..1000).flat_map(|x| x..x+1000)
166 }
167
168 bench_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
174 bench_sums! {
175 bench_enumerate_sum,
176 bench_enumerate_ref_sum,
177 (0i64..1000000).enumerate().map(|(i, x)| x * i as i64)
178 }
179
180 bench_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
186 bench_sums! {
187 bench_filter_sum,
188 bench_filter_ref_sum,
189 (0i64..1000000).filter(|x| x % 3 == 0)
190 }
191
192 bench_sums! {
193 bench_filter_chain_sum,
194 bench_filter_chain_ref_sum,
195 (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0)
196 }
197
198 bench_sums! {
199 bench_filter_map_sum,
200 bench_filter_map_ref_sum,
201 (0i64..1000000).filter_map(|x| x.checked_mul(x))
202 }
203
204 bench_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
210 bench_sums! {
211 bench_fuse_sum,
212 bench_fuse_ref_sum,
213 (0i64..1000000).fuse()
214 }
215
216 bench_sums! {
217 bench_fuse_chain_sum,
218 bench_fuse_chain_ref_sum,
219 (0i64..1000000).chain(0..1000000).fuse()
220 }
221
222 bench_sums! {
223 bench_inspect_sum,
224 bench_inspect_ref_sum,
225 (0i64..1000000).inspect(|_| {})
226 }
227
228 bench_sums! {
229 bench_inspect_chain_sum,
230 bench_inspect_chain_ref_sum,
231 (0i64..1000000).chain(0..1000000).inspect(|_| {})
232 }
233
234 bench_sums! {
235 bench_peekable_sum,
236 bench_peekable_ref_sum,
237 (0i64..1000000).peekable()
238 }
239
240 bench_sums! {
241 bench_peekable_chain_sum,
242 bench_peekable_chain_ref_sum,
243 (0i64..1000000).chain(0..1000000).peekable()
244 }
245
246 bench_sums! {
247 bench_skip_sum,
248 bench_skip_ref_sum,
249 (0i64..1000000).skip(1000)
250 }
251
252 bench_sums! {
253 bench_skip_chain_sum,
254 bench_skip_chain_ref_sum,
255 (0i64..1000000).chain(0..1000000).skip(1000)
256 }
257
258 bench_sums! {
259 bench_skip_while_sum,
260 bench_skip_while_ref_sum,
261 (0i64..1000000).skip_while(|&x| x < 1000)
262 }
263
264 bench_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 }
269
270 bench_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 }
275
276 bench_sums! {
277 bench_cycle_take_sum,
278 bench_cycle_take_ref_sum,
279 (0i64..10000).cycle().take(1000000)
280 }
281
282 // Checks whether Skip<Zip<A,B>> is as fast as Zip<Skip<A>, Skip<B>>, from
283 // https://users.rust-lang.org/t/performance-difference-between-iterator-zip-and-skip-order/15743
284 #[bench]
285 fn bench_zip_then_skip(b: &mut Bencher) {
286 let v: Vec<_> = (0..100_000).collect();
287 let t: Vec<_> = (0..100_000).collect();
288
289 b.iter(|| {
290 let s = v
291 .iter()
292 .zip(t.iter())
293 .skip(10000)
294 .take_while(|t| *t.0 < 10100)
295 .map(|(a, b)| *a + *b)
296 .sum::<u64>();
297 assert_eq!(s, 2009900);
298 });
299 }
300 #[bench]
301 fn bench_skip_then_zip(b: &mut Bencher) {
302 let v: Vec<_> = (0..100_000).collect();
303 let t: Vec<_> = (0..100_000).collect();
304
305 b.iter(|| {
306 let s = v
307 .iter()
308 .skip(10000)
309 .zip(t.iter().skip(10000))
310 .take_while(|t| *t.0 < 10100)
311 .map(|(a, b)| *a + *b)
312 .sum::<u64>();
313 assert_eq!(s, 2009900);
314 });
315 }
316
317 #[bench]
318 fn bench_filter_count(b: &mut Bencher) {
319 b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())
320 }
321
322 #[bench]
323 fn bench_filter_ref_count(b: &mut Bencher) {
324 b.iter(|| (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count())
325 }
326
327 #[bench]
328 fn bench_filter_chain_count(b: &mut Bencher) {
329 b.iter(|| (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count())
330 }
331
332 #[bench]
333 fn bench_filter_chain_ref_count(b: &mut Bencher) {
334 b.iter(|| {
335 (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
336 })
337 }
338
339 #[bench]
340 fn bench_partial_cmp(b: &mut Bencher) {
341 b.iter(|| (0..100000).map(black_box).partial_cmp((0..100000).map(black_box)))
342 }
343
344 #[bench]
345 fn bench_lt(b: &mut Bencher) {
346 b.iter(|| (0..100000).map(black_box).lt((0..100000).map(black_box)))
347 }