Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seq: use Floyd's combination algorithm to sample indices #479

Merged
merged 14 commits into from Jul 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,11 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md).

You may also find the [Update Guide](UPDATING.md) useful.

## [0.6.0] - Unreleased

### Sequences module
- Optimised and changed return type of the `sample_indices` function. (#479)

## [0.5.4] - 2018-07-11
### Platform support
- Make `OsRng` work via WASM/stdweb for WebWorkers
Expand Down
57 changes: 33 additions & 24 deletions benches/seq.rs
@@ -1,4 +1,5 @@
#![feature(test)]
#![allow(non_snake_case)]

extern crate test;
extern crate rand;
Expand Down Expand Up @@ -27,28 +28,31 @@ fn seq_slice_choose_1_of_1000(b: &mut Bencher) {
})
}

#[bench]
fn seq_slice_choose_multiple_1_of_1000(b: &mut Bencher) {
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
let x : &[usize] = &[1; 1000];
b.iter(|| {
x.choose_multiple(&mut rng, 1).cloned().next()
})
}

#[bench]
fn seq_slice_choose_multiple_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(|| {
for (v, slot) in x.choose_multiple(&mut rng, buf.len()).zip(buf.iter_mut()) {
*slot = *v;
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]
})
}
buf
})
}
}

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_100(b: &mut Bencher) {
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
Expand Down Expand Up @@ -78,17 +82,22 @@ fn seq_iter_choose_multiple_fill_10_of_100(b: &mut Bencher) {
}

macro_rules! sample_indices {
($name:ident, $amount:expr, $length:expr) => {
($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(|| {
sample_indices(&mut rng, $length, $amount)
index::$fn(&mut rng, $length, $amount)
})
}
}
}

sample_indices!(seq_sample_indices_10_of_1k, 10, 1000);
sample_indices!(seq_sample_indices_50_of_1k, 50, 1000);
sample_indices!(seq_sample_indices_100_of_1k, 100, 1000);
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);
2 changes: 1 addition & 1 deletion src/lib.rs
Expand Up @@ -234,7 +234,7 @@
#![cfg_attr(feature = "wasm-bindgen", feature(wasm_import_module))]

#[cfg(feature = "std")] extern crate core;
#[cfg(all(feature = "alloc", not(feature="std")))] extern crate alloc;
#[cfg(all(feature = "alloc", not(feature="std")))] #[macro_use] extern crate alloc;

#[cfg(feature="simd_support")] extern crate packed_simd;

Expand Down