Skip to content

Commit 8f2290f

Browse files
authored
Merge pull request #483 from rust-lang-nursery/seq
Sequence functionality: API revisions
2 parents 4228914 + 1b118c2 commit 8f2290f

7 files changed

Lines changed: 518 additions & 208 deletions

File tree

benches/misc.rs

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const RAND_BENCH_N: u64 = 1000;
88
use test::Bencher;
99

1010
use rand::prelude::*;
11-
use rand::seq::*;
1211

1312
#[bench]
1413
fn misc_gen_bool_const(b: &mut Bencher) {
@@ -108,59 +107,6 @@ sample_binomial!(misc_binomial_100, 100, 0.99);
108107
sample_binomial!(misc_binomial_1000, 1000, 0.01);
109108
sample_binomial!(misc_binomial_1e12, 1000_000_000_000, 0.2);
110109

111-
#[bench]
112-
fn misc_shuffle_100(b: &mut Bencher) {
113-
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
114-
let x : &mut [usize] = &mut [1; 100];
115-
b.iter(|| {
116-
rng.shuffle(x);
117-
x[0]
118-
})
119-
}
120-
121-
#[bench]
122-
fn misc_sample_iter_10_of_100(b: &mut Bencher) {
123-
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
124-
let x : &[usize] = &[1; 100];
125-
b.iter(|| {
126-
sample_iter(&mut rng, x, 10).unwrap_or_else(|e| e)
127-
})
128-
}
129-
130-
#[bench]
131-
fn misc_sample_slice_10_of_100(b: &mut Bencher) {
132-
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
133-
let x : &[usize] = &[1; 100];
134-
b.iter(|| {
135-
sample_slice(&mut rng, x, 10)
136-
})
137-
}
138-
139-
#[bench]
140-
fn misc_sample_slice_ref_10_of_100(b: &mut Bencher) {
141-
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
142-
let x : &[usize] = &[1; 100];
143-
b.iter(|| {
144-
sample_slice_ref(&mut rng, x, 10)
145-
})
146-
}
147-
148-
macro_rules! sample_indices {
149-
($name:ident, $amount:expr, $length:expr) => {
150-
#[bench]
151-
fn $name(b: &mut Bencher) {
152-
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
153-
b.iter(|| {
154-
sample_indices(&mut rng, $length, $amount)
155-
})
156-
}
157-
}
158-
}
159-
160-
sample_indices!(misc_sample_indices_10_of_1k, 10, 1000);
161-
sample_indices!(misc_sample_indices_50_of_1k, 50, 1000);
162-
sample_indices!(misc_sample_indices_100_of_1k, 100, 1000);
163-
164110
#[bench]
165111
fn gen_1k_iter_repeat(b: &mut Bencher) {
166112
use std::iter;

benches/seq.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#![feature(test)]
2+
3+
extern crate test;
4+
extern crate rand;
5+
6+
use test::Bencher;
7+
8+
use rand::prelude::*;
9+
use rand::seq::*;
10+
11+
#[bench]
12+
fn seq_shuffle_100(b: &mut Bencher) {
13+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
14+
let x : &mut [usize] = &mut [1; 100];
15+
b.iter(|| {
16+
x.shuffle(&mut rng);
17+
x[0]
18+
})
19+
}
20+
21+
#[bench]
22+
fn seq_slice_choose_1_of_1000(b: &mut Bencher) {
23+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
24+
let x : &[usize] = &[1; 1000];
25+
b.iter(|| {
26+
x.choose(&mut rng)
27+
})
28+
}
29+
30+
#[bench]
31+
fn seq_slice_choose_multiple_1_of_1000(b: &mut Bencher) {
32+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
33+
let x : &[usize] = &[1; 1000];
34+
b.iter(|| {
35+
x.choose_multiple(&mut rng, 1).cloned().next()
36+
})
37+
}
38+
39+
#[bench]
40+
fn seq_slice_choose_multiple_10_of_100(b: &mut Bencher) {
41+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
42+
let x : &[usize] = &[1; 100];
43+
let mut buf = [0; 10];
44+
b.iter(|| {
45+
for (v, slot) in x.choose_multiple(&mut rng, buf.len()).zip(buf.iter_mut()) {
46+
*slot = *v;
47+
}
48+
buf
49+
})
50+
}
51+
52+
#[bench]
53+
fn seq_iter_choose_from_100(b: &mut Bencher) {
54+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
55+
let x : &[usize] = &[1; 100];
56+
b.iter(|| {
57+
x.iter().cloned().choose(&mut rng)
58+
})
59+
}
60+
61+
#[bench]
62+
fn seq_iter_choose_multiple_10_of_100(b: &mut Bencher) {
63+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
64+
let x : &[usize] = &[1; 100];
65+
b.iter(|| {
66+
x.iter().cloned().choose_multiple(&mut rng, 10)
67+
})
68+
}
69+
70+
#[bench]
71+
fn seq_iter_choose_multiple_fill_10_of_100(b: &mut Bencher) {
72+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
73+
let x : &[usize] = &[1; 100];
74+
let mut buf = [0; 10];
75+
b.iter(|| {
76+
x.iter().cloned().choose_multiple_fill(&mut rng, &mut buf)
77+
})
78+
}
79+
80+
macro_rules! sample_indices {
81+
($name:ident, $amount:expr, $length:expr) => {
82+
#[bench]
83+
fn $name(b: &mut Bencher) {
84+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
85+
b.iter(|| {
86+
sample_indices(&mut rng, $length, $amount)
87+
})
88+
}
89+
}
90+
}
91+
92+
sample_indices!(seq_sample_indices_10_of_1k, 10, 1000);
93+
sample_indices!(seq_sample_indices_50_of_1k, 50, 1000);
94+
sample_indices!(seq_sample_indices_100_of_1k, 100, 1000);

examples/monty-hall.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ fn simulate<R: Rng>(random_door: &Uniform<u32>, rng: &mut R)
6363
// Returns the door the game host opens given our choice and knowledge of
6464
// where the car is. The game host will never open the door with the car.
6565
fn game_host_open<R: Rng>(car: u32, choice: u32, rng: &mut R) -> u32 {
66-
let choices = free_doors(&[car, choice]);
67-
rand::seq::sample_slice(rng, &choices, 1)[0]
66+
use rand::seq::SliceRandom;
67+
*free_doors(&[car, choice]).choose(rng).unwrap()
6868
}
6969

7070
// Returns the door we switch to, given our current choice and

src/lib.rs

Lines changed: 18 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -588,64 +588,35 @@ pub trait Rng: RngCore {
588588

589589
/// Return a random element from `values`.
590590
///
591-
/// Return `None` if `values` is empty.
592-
///
593-
/// # Example
594-
///
595-
/// ```
596-
/// use rand::{thread_rng, Rng};
597-
///
598-
/// let choices = [1, 2, 4, 8, 16, 32];
599-
/// let mut rng = thread_rng();
600-
/// println!("{:?}", rng.choose(&choices));
601-
/// assert_eq!(rng.choose(&choices[..0]), None);
602-
/// ```
591+
/// Deprecated: use [`SliceRandom::choose`] instead.
592+
///
593+
/// [`SliceRandom::choose`]: seq/trait.SliceRandom.html#method.choose
594+
#[deprecated(since="0.6.0", note="use SliceRandom::choose instead")]
603595
fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
604-
if values.is_empty() {
605-
None
606-
} else {
607-
Some(&values[self.gen_range(0, values.len())])
608-
}
596+
use seq::SliceRandom;
597+
values.choose(self)
609598
}
610599

611600
/// Return a mutable pointer to a random element from `values`.
612601
///
613-
/// Return `None` if `values` is empty.
602+
/// Deprecated: use [`SliceRandom::choose_mut`] instead.
603+
///
604+
/// [`SliceRandom::choose_mut`]: seq/trait.SliceRandom.html#method.choose_mut
605+
#[deprecated(since="0.6.0", note="use SliceRandom::choose_mut instead")]
614606
fn choose_mut<'a, T>(&mut self, values: &'a mut [T]) -> Option<&'a mut T> {
615-
if values.is_empty() {
616-
None
617-
} else {
618-
let len = values.len();
619-
Some(&mut values[self.gen_range(0, len)])
620-
}
607+
use seq::SliceRandom;
608+
values.choose_mut(self)
621609
}
622610

623611
/// Shuffle a mutable slice in place.
624612
///
625-
/// This applies Durstenfeld's algorithm for the [Fisher–Yates shuffle](
626-
/// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm)
627-
/// which produces an unbiased permutation.
628-
///
629-
/// # Example
630-
///
631-
/// ```
632-
/// use rand::{thread_rng, Rng};
633-
///
634-
/// let mut rng = thread_rng();
635-
/// let mut y = [1, 2, 3];
636-
/// rng.shuffle(&mut y);
637-
/// println!("{:?}", y);
638-
/// rng.shuffle(&mut y);
639-
/// println!("{:?}", y);
640-
/// ```
613+
/// Deprecated: use [`SliceRandom::shuffle`] instead.
614+
///
615+
/// [`SliceRandom::shuffle`]: seq/trait.SliceRandom.html#method.shuffle
616+
#[deprecated(since="0.6.0", note="use SliceRandom::shuffle instead")]
641617
fn shuffle<T>(&mut self, values: &mut [T]) {
642-
let mut i = values.len();
643-
while i >= 2 {
644-
// invariant: elements with index >= i have been locked in place.
645-
i -= 1;
646-
// lock element i in place.
647-
values.swap(i, self.gen_range(0, i + 1));
648-
}
618+
use seq::SliceRandom;
619+
values.shuffle(self)
649620
}
650621
}
651622

@@ -999,46 +970,13 @@ mod test {
999970
}
1000971
}
1001972

1002-
#[test]
1003-
fn test_choose() {
1004-
let mut r = rng(107);
1005-
assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1));
1006-
1007-
let v: &[isize] = &[];
1008-
assert_eq!(r.choose(v), None);
1009-
}
1010-
1011-
#[test]
1012-
fn test_shuffle() {
1013-
let mut r = rng(108);
1014-
let empty: &mut [isize] = &mut [];
1015-
r.shuffle(empty);
1016-
let mut one = [1];
1017-
r.shuffle(&mut one);
1018-
let b: &[_] = &[1];
1019-
assert_eq!(one, b);
1020-
1021-
let mut two = [1, 2];
1022-
r.shuffle(&mut two);
1023-
assert!(two == [1, 2] || two == [2, 1]);
1024-
1025-
let mut x = [1, 1, 1];
1026-
r.shuffle(&mut x);
1027-
let b: &[_] = &[1, 1, 1];
1028-
assert_eq!(x, b);
1029-
}
1030-
1031973
#[test]
1032974
fn test_rng_trait_object() {
1033975
use distributions::{Distribution, Standard};
1034976
let mut rng = rng(109);
1035977
let mut r = &mut rng as &mut RngCore;
1036978
r.next_u32();
1037979
r.gen::<i32>();
1038-
let mut v = [1, 1, 1];
1039-
r.shuffle(&mut v);
1040-
let b: &[_] = &[1, 1, 1];
1041-
assert_eq!(v, b);
1042980
assert_eq!(r.gen_range(0, 1), 0);
1043981
let _c: u8 = Standard.sample(&mut r);
1044982
}
@@ -1051,10 +989,6 @@ mod test {
1051989
let mut r = Box::new(rng) as Box<RngCore>;
1052990
r.next_u32();
1053991
r.gen::<i32>();
1054-
let mut v = [1, 1, 1];
1055-
r.shuffle(&mut v);
1056-
let b: &[_] = &[1, 1, 1];
1057-
assert_eq!(v, b);
1058992
assert_eq!(r.gen_range(0, 1), 0);
1059993
let _c: u8 = Standard.sample(&mut r);
1060994
}

src/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
#[doc(no_inline)] #[cfg(feature="std")] pub use rngs::ThreadRng;
2727
#[doc(no_inline)] pub use {Rng, RngCore, CryptoRng, SeedableRng};
2828
#[doc(no_inline)] #[cfg(feature="std")] pub use {FromEntropy, random, thread_rng};
29+
#[doc(no_inline)] pub use seq::{SliceRandom, IteratorRandom};

src/rngs/thread.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ mod test {
132132
use Rng;
133133
let mut r = ::thread_rng();
134134
r.gen::<i32>();
135-
let mut v = [1, 1, 1];
136-
r.shuffle(&mut v);
137-
let b: &[_] = &[1, 1, 1];
138-
assert_eq!(v, b);
139135
assert_eq!(r.gen_range(0, 1), 0);
140136
}
141137
}

0 commit comments

Comments
 (0)