// Copyright 2018 Developers of the Rand project. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(test)] #![allow(non_snake_case)] extern crate test; extern crate rand; use test::Bencher; use rand::prelude::*; use rand::seq::*; use std::mem::size_of; const RAND_BENCH_N: u64 = 1000; #[bench] fn seq_shuffle_100(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &mut [usize] = &mut [1; 100]; b.iter(|| { x.shuffle(&mut rng); x[0] }) } #[bench] fn seq_slice_choose_1_of_1000(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &mut [usize] = &mut [1; 1000]; for i in 0..1000 { x[i] = i; } b.iter(|| { let mut s = 0; for _ in 0..RAND_BENCH_N { s += x.choose(&mut rng).unwrap(); } s }); b.bytes = size_of::() as u64 * ::RAND_BENCH_N; } macro_rules! seq_slice_choose_multiple { ($name:ident, $amount:expr, $length:expr) => { #[bench] fn $name(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &[i32] = &[$amount; $length]; let mut result = [0i32; $amount]; b.iter(|| { // Collect full result to prevent unwanted shortcuts getting // first element (in case sample_indices returns an iterator). for (slot, sample) in result.iter_mut().zip( x.choose_multiple(&mut rng, $amount)) { *slot = *sample; } result[$amount-1] }) } } } seq_slice_choose_multiple!(seq_slice_choose_multiple_1_of_1000, 1, 1000); seq_slice_choose_multiple!(seq_slice_choose_multiple_950_of_1000, 950, 1000); seq_slice_choose_multiple!(seq_slice_choose_multiple_10_of_100, 10, 100); seq_slice_choose_multiple!(seq_slice_choose_multiple_90_of_100, 90, 100); #[bench] fn seq_iter_choose_from_1000(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &mut [usize] = &mut [1; 1000]; for i in 0..1000 { x[i] = i; } b.iter(|| { let mut s = 0; for _ in 0..RAND_BENCH_N { s += x.iter().choose(&mut rng).unwrap(); } s }); b.bytes = size_of::() as u64 * ::RAND_BENCH_N; } #[derive(Clone)] struct UnhintedIterator { iter: I, } impl Iterator for UnhintedIterator { type Item = I::Item; fn next(&mut self) -> Option { self.iter.next() } } #[derive(Clone)] struct WindowHintedIterator { iter: I, window_size: usize, } impl Iterator for WindowHintedIterator { type Item = I::Item; fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { (std::cmp::min(self.iter.len(), self.window_size), None) } } #[bench] fn seq_iter_unhinted_choose_from_1000(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &[usize] = &[1; 1000]; b.iter(|| { UnhintedIterator { iter: x.iter() }.choose(&mut rng).unwrap() }) } #[bench] fn seq_iter_window_hinted_choose_from_1000(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &[usize] = &[1; 1000]; b.iter(|| { WindowHintedIterator { iter: x.iter(), window_size: 7 }.choose(&mut rng) }) } #[bench] fn seq_iter_choose_multiple_10_of_100(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &[usize] = &[1; 100]; b.iter(|| { x.iter().cloned().choose_multiple(&mut rng, 10) }) } #[bench] fn seq_iter_choose_multiple_fill_10_of_100(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); let x : &[usize] = &[1; 100]; let mut buf = [0; 10]; b.iter(|| { x.iter().cloned().choose_multiple_fill(&mut rng, &mut buf) }) } macro_rules! sample_indices { ($name:ident, $fn:ident, $amount:expr, $length:expr) => { #[bench] fn $name(b: &mut Bencher) { let mut rng = SmallRng::from_rng(thread_rng()).unwrap(); b.iter(|| { index::$fn(&mut rng, $length, $amount) }) } } } sample_indices!(misc_sample_indices_1_of_1k, sample, 1, 1000); sample_indices!(misc_sample_indices_10_of_1k, sample, 10, 1000); sample_indices!(misc_sample_indices_100_of_1k, sample, 100, 1000); sample_indices!(misc_sample_indices_100_of_1M, sample, 100, 1000_000); sample_indices!(misc_sample_indices_100_of_1G, sample, 100, 1000_000_000); sample_indices!(misc_sample_indices_200_of_1G, sample, 200, 1000_000_000); sample_indices!(misc_sample_indices_400_of_1G, sample, 400, 1000_000_000); sample_indices!(misc_sample_indices_600_of_1G, sample, 600, 1000_000_000);