2 use test::{black_box, Bencher};
5 fn bench_rposition(b: &mut Bencher) {
6 let it: Vec<usize> = (0..300).collect();
8 it.iter().rposition(|&x| x <= 150);
13 fn bench_skip_while(b: &mut Bencher) {
26 fn bench_multiple_take(b: &mut Bencher) {
27 let mut it = (0..42).cycle();
29 let n = it.next().unwrap();
31 it.clone().take(it.next().unwrap()).all(|_| true);
36 fn scatter(x: i32) -> i32 {
41 fn bench_max_by_key(b: &mut Bencher) {
44 it.map(black_box).max_by_key(|&x| scatter(x))
48 // https://www.reddit.com/r/rust/comments/31syce/using_iterators_to_find_the_index_of_the_min_or/
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
55 let mut data = vec![0; 1638];
58 b.iter(|| max_index_iter(&data));
62 fn bench_max(b: &mut Bencher) {
65 it.map(black_box).map(scatter).max()
69 pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
70 for (a, b) in ys.iter_mut().zip(xs) {
75 pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
76 for (a, b) in ys.iter_mut().zip(xs) {
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))
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));
95 /// `Iterator::for_each` implemented as a plain loop.
96 fn for_each_loop<I, F>(iter: I, mut f: F)
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)
113 iter.fold((), move |(), item| f(item));
117 fn bench_for_each_chain_loop(b: &mut Bencher) {
120 let iter = (0i64..1000000).chain(0..1000000).map(black_box);
121 for_each_loop(iter, |x| acc += x);
127 fn bench_for_each_chain_fold(b: &mut Bencher) {
130 let iter = (0i64..1000000).chain(0..1000000).map(black_box);
131 for_each_fold(iter, |x| acc += x);
137 fn bench_for_each_chain_ref_fold(b: &mut Bencher) {
140 let mut iter = (0i64..1000000).chain(0..1000000).map(black_box);
141 for_each_fold(iter.by_ref(), |x| acc += x);
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) => {
151 fn $bench_sum(b: &mut Bencher) {
152 b.iter(|| -> i64 { $iter.map(black_box).sum() });
156 fn $bench_ref_sum(b: &mut Bencher) {
157 b.iter(|| -> i64 { $iter.map(black_box).by_ref().sum() });
164 bench_flat_map_ref_sum,
165 (0i64..1000).flat_map(|x| x..x+1000)
169 bench_flat_map_chain_sum,
170 bench_flat_map_chain_ref_sum,
171 (0i64..1000000).flat_map(|x| once(x).chain(once(x)))
176 bench_enumerate_ref_sum,
177 (0i64..1000000).enumerate().map(|(i, x)| x * i as i64)
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)
188 bench_filter_ref_sum,
189 (0i64..1000000).filter(|x| x % 3 == 0)
193 bench_filter_chain_sum,
194 bench_filter_chain_ref_sum,
195 (0i64..1000000).chain(0..1000000).filter(|x| x % 3 == 0)
199 bench_filter_map_sum,
200 bench_filter_map_ref_sum,
201 (0i64..1000000).filter_map(|x| x.checked_mul(x))
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))
213 (0i64..1000000).fuse()
217 bench_fuse_chain_sum,
218 bench_fuse_chain_ref_sum,
219 (0i64..1000000).chain(0..1000000).fuse()
224 bench_inspect_ref_sum,
225 (0i64..1000000).inspect(|_| {})
229 bench_inspect_chain_sum,
230 bench_inspect_chain_ref_sum,
231 (0i64..1000000).chain(0..1000000).inspect(|_| {})
236 bench_peekable_ref_sum,
237 (0i64..1000000).peekable()
241 bench_peekable_chain_sum,
242 bench_peekable_chain_ref_sum,
243 (0i64..1000000).chain(0..1000000).peekable()
249 (0i64..1000000).skip(1000)
253 bench_skip_chain_sum,
254 bench_skip_chain_ref_sum,
255 (0i64..1000000).chain(0..1000000).skip(1000)
259 bench_skip_while_sum,
260 bench_skip_while_ref_sum,
261 (0i64..1000000).skip_while(|&x| x < 1000)
265 bench_skip_while_chain_sum,
266 bench_skip_while_chain_ref_sum,
267 (0i64..1000000).chain(0..1000000).skip_while(|&x| x < 1000)
271 bench_take_while_chain_sum,
272 bench_take_while_chain_ref_sum,
273 (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111)
277 bench_cycle_take_sum,
278 bench_cycle_take_ref_sum,
279 (0..10000).cycle().take(1000000)
283 bench_cycle_skip_take_sum,
284 bench_cycle_skip_take_ref_sum,
285 (0..100000).cycle().skip(1000000).take(1000000)
289 bench_cycle_take_skip_sum,
290 bench_cycle_take_skip_ref_sum,
291 (0..100000).cycle().take(1000000).skip(100000)
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))
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
307 fn bench_zip_then_skip(b: &mut Bencher) {
308 let v: Vec<_> = (0..100_000).collect();
309 let t: Vec<_> = (0..100_000).collect();
316 .take_while(|t| *t.0 < 10100)
317 .map(|(a, b)| *a + *b)
319 assert_eq!(s, 2009900);
323 fn bench_skip_then_zip(b: &mut Bencher) {
324 let v: Vec<_> = (0..100_000).collect();
325 let t: Vec<_> = (0..100_000).collect();
331 .zip(t.iter().skip(10000))
332 .take_while(|t| *t.0 < 10100)
333 .map(|(a, b)| *a + *b)
335 assert_eq!(s, 2009900);
340 fn bench_filter_count(b: &mut Bencher) {
341 b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())
345 fn bench_filter_ref_count(b: &mut Bencher) {
346 b.iter(|| (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count())
350 fn bench_filter_chain_count(b: &mut Bencher) {
351 b.iter(|| (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count())
355 fn bench_filter_chain_ref_count(b: &mut Bencher) {
357 (0i64..1000000).chain(0..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
362 fn bench_partial_cmp(b: &mut Bencher) {
363 b.iter(|| (0..100000).map(black_box).partial_cmp((0..100000).map(black_box)))
367 fn bench_lt(b: &mut Bencher) {
368 b.iter(|| (0..100000).map(black_box).lt((0..100000).map(black_box)))