Skip to content

Commit 2a8cb17

Browse files
authored
Merge pull request #296 from vks/remove-random
Deprecate `random` and `weak_rng`, add `SmallRng`
2 parents 50f8736 + 887efe1 commit 2a8cb17

File tree

7 files changed

+107
-32
lines changed

7 files changed

+107
-32
lines changed

benches/misc.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ extern crate rand;
55

66
use test::{black_box, Bencher};
77

8-
use rand::{Rng, weak_rng};
8+
use rand::{SeedableRng, SmallRng, Rng, thread_rng};
99
use rand::seq::*;
1010

1111
#[bench]
1212
fn misc_shuffle_100(b: &mut Bencher) {
13-
let mut rng = weak_rng();
13+
let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
1414
let x : &mut [usize] = &mut [1; 100];
1515
b.iter(|| {
1616
rng.shuffle(x);
@@ -20,7 +20,7 @@ fn misc_shuffle_100(b: &mut Bencher) {
2020

2121
#[bench]
2222
fn misc_sample_iter_10_of_100(b: &mut Bencher) {
23-
let mut rng = weak_rng();
23+
let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
2424
let x : &[usize] = &[1; 100];
2525
b.iter(|| {
2626
black_box(sample_iter(&mut rng, x, 10).unwrap_or_else(|e| e));
@@ -29,7 +29,7 @@ fn misc_sample_iter_10_of_100(b: &mut Bencher) {
2929

3030
#[bench]
3131
fn misc_sample_slice_10_of_100(b: &mut Bencher) {
32-
let mut rng = weak_rng();
32+
let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
3333
let x : &[usize] = &[1; 100];
3434
b.iter(|| {
3535
black_box(sample_slice(&mut rng, x, 10));
@@ -38,7 +38,7 @@ fn misc_sample_slice_10_of_100(b: &mut Bencher) {
3838

3939
#[bench]
4040
fn misc_sample_slice_ref_10_of_100(b: &mut Bencher) {
41-
let mut rng = weak_rng();
41+
let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
4242
let x : &[usize] = &[1; 100];
4343
b.iter(|| {
4444
black_box(sample_slice_ref(&mut rng, x, 10));
@@ -49,7 +49,7 @@ macro_rules! sample_indices {
4949
($name:ident, $amount:expr, $length:expr) => {
5050
#[bench]
5151
fn $name(b: &mut Bencher) {
52-
let mut rng = weak_rng();
52+
let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
5353
b.iter(|| {
5454
black_box(sample_indices(&mut rng, $length, $amount));
5555
})

src/distributions/exponential.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ use distributions::{ziggurat, ziggurat_tables, Distribution};
3030
///
3131
/// # Example
3232
/// ```rust
33-
/// use rand::{weak_rng, Rng};
33+
/// use rand::{NewRng, SmallRng, Rng};
3434
/// use rand::distributions::Exp1;
3535
///
36-
/// let val: f64 = weak_rng().sample(Exp1);
36+
/// let val: f64 = SmallRng::new().unwrap().sample(Exp1);
3737
/// println!("{}", val);
3838
/// ```
3939
#[derive(Clone, Copy, Debug)]

src/distributions/float.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ macro_rules! float_impls {
4949
///
5050
/// # Example
5151
/// ```rust
52-
/// use rand::{weak_rng, Rng};
52+
/// use rand::{NewRng, SmallRng, Rng};
5353
/// use rand::distributions::Uniform;
5454
///
55-
/// let val: f32 = weak_rng().sample(Uniform);
55+
/// let val: f32 = SmallRng::new().unwrap().sample(Uniform);
5656
/// println!("f32 from (0,1): {}", val);
5757
/// ```
5858
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {

src/distributions/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
163163
///
164164
/// # Example
165165
/// ```rust
166-
/// use rand::{weak_rng, Rng};
166+
/// use rand::{NewRng, SmallRng, Rng};
167167
/// use rand::distributions::Uniform;
168168
///
169-
/// let val: f32 = weak_rng().sample(Uniform);
169+
/// let val: f32 = SmallRng::new().unwrap().sample(Uniform);
170170
/// println!("f32 from [0,1): {}", val);
171171
/// ```
172172
///

src/distributions/normal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ use distributions::{ziggurat, ziggurat_tables, Distribution, Uniform};
2828
///
2929
/// # Example
3030
/// ```rust
31-
/// use rand::{weak_rng, Rng};
31+
/// use rand::{NewRng, SmallRng, Rng};
3232
/// use rand::distributions::StandardNormal;
3333
///
34-
/// let val: f64 = weak_rng().sample(StandardNormal);
34+
/// let val: f64 = SmallRng::new().unwrap().sample(StandardNormal);
3535
/// println!("{}", val);
3636
/// ```
3737
#[derive(Clone, Copy, Debug)]

src/lib.rs

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010

1111
//! Utilities for random number generation
1212
//!
13-
//! The key functions are `random()` and `Rng::gen()`. These are polymorphic and
14-
//! so can be used to generate any type supporting the [`Uniform`] distribution
15-
//! (i.e. `T` where `Uniform`: `Distribution<T>`). Type inference
16-
//! means that often a simple call to `rand::random()` or `rng.gen()` will
17-
//! suffice, but sometimes an annotation is required, e.g.
18-
//! `rand::random::<f64>()`.
13+
//! The key function is `Rng::gen()`. It is polymorphic and so can be used to
14+
//! generate any type supporting the [`Uniform`] distribution (i.e. `T` where
15+
//! `Uniform`: `Distribution<T>`). Type inference means that often a simple call
16+
//! to `rng.gen()` will suffice, but sometimes an annotation is required, e.g.
17+
//! `rng.gen::<f64>()`.
1918
//!
2019
//! See the `distributions` submodule for sampling random numbers from
2120
//! distributions like normal and exponential.
@@ -88,11 +87,6 @@
8887
//! }
8988
//! ```
9089
//!
91-
//! ```rust
92-
//! let tuple = rand::random::<(f64, char)>();
93-
//! println!("{:?}", tuple)
94-
//! ```
95-
//!
9690
//! ## Monte Carlo estimation of π
9791
//!
9892
//! For this example, imagine we have a square with sides of length 2 and a unit
@@ -289,7 +283,8 @@ pub use error::{ErrorKind, Error};
289283

290284
// convenience and derived rngs
291285
#[cfg(feature="std")] pub use entropy_rng::EntropyRng;
292-
#[cfg(feature="std")] pub use thread_rng::{ThreadRng, thread_rng, random};
286+
#[cfg(feature="std")] pub use thread_rng::{ThreadRng, thread_rng};
287+
#[cfg(feature="std")] #[allow(deprecated)] pub use thread_rng::random;
293288

294289
use distributions::{Distribution, Uniform, Range};
295290
use distributions::range::SampleRange;
@@ -1091,6 +1086,81 @@ impl SeedableRng for StdRng {
10911086
}
10921087
}
10931088

1089+
/// An RNG recommended when small state, cheap initialization and good
1090+
/// performance are required. The PRNG algorithm in `SmallRng` is choosen to be
1091+
/// efficient on the current platform, **without consideration for cryptography
1092+
/// or security**. The size of its state is much smaller than for `StdRng`.
1093+
///
1094+
/// Reproducibility of output from this generator is however not required, thus
1095+
/// future library versions may use a different internal generator with
1096+
/// different output. Further, this generator may not be portable and can
1097+
/// produce different output depending on the architecture. If you require
1098+
/// reproducible output, use a named RNG, for example `XorShiftRng`.
1099+
///
1100+
/// The current algorithm used on all platforms is [Xorshift].
1101+
///
1102+
/// # Examples
1103+
///
1104+
/// Initializing `StdRng` with a random seed can be done using `NewRng`:
1105+
///
1106+
/// ```
1107+
/// use rand::{NewRng, SmallRng};
1108+
///
1109+
/// // Create small, cheap to initialize and fast RNG with a random seed.
1110+
/// // The randomness is supplied by the operating system.
1111+
/// let mut small_rng = SmallRng::new().unwrap();
1112+
/// ```
1113+
///
1114+
/// When initializing a lot of `SmallRng`, using `thread_rng` can be more
1115+
/// efficient:
1116+
///
1117+
/// ```
1118+
/// use rand::{SeedableRng, SmallRng, thread_rng};
1119+
///
1120+
/// // Create a big, expensive to initialize and slower, but unpredictable RNG.
1121+
/// // This is cached and done only once per thread.
1122+
/// let mut thread_rng = thread_rng();
1123+
/// // Create small, cheap to initialize and fast RNG with a random seed.
1124+
/// // This is very unlikely to fail.
1125+
/// let mut small_rng = SmallRng::from_rng(&mut thread_rng).unwrap();
1126+
/// ```
1127+
///
1128+
/// [Xorshift]: struct.XorShiftRng.html
1129+
#[derive(Clone, Debug)]
1130+
pub struct SmallRng(XorShiftRng);
1131+
1132+
impl RngCore for SmallRng {
1133+
fn next_u32(&mut self) -> u32 {
1134+
self.0.next_u32()
1135+
}
1136+
1137+
fn next_u64(&mut self) -> u64 {
1138+
self.0.next_u64()
1139+
}
1140+
1141+
fn fill_bytes(&mut self, dest: &mut [u8]) {
1142+
self.0.fill_bytes(dest);
1143+
}
1144+
1145+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
1146+
self.0.try_fill_bytes(dest)
1147+
}
1148+
}
1149+
1150+
impl SeedableRng for SmallRng {
1151+
type Seed = <XorShiftRng as SeedableRng>::Seed;
1152+
1153+
fn from_seed(seed: Self::Seed) -> Self {
1154+
SmallRng(XorShiftRng::from_seed(seed))
1155+
}
1156+
1157+
fn from_rng<R: Rng>(rng: &mut R) -> Result<Self, Error> {
1158+
XorShiftRng::from_rng(rng).map(|rng| SmallRng(rng))
1159+
}
1160+
}
1161+
1162+
/// DEPRECATED: use `SmallRng` instead.
1163+
///
10941164
/// Create a weak random number generator with a default algorithm and seed.
10951165
///
10961166
/// It returns the fastest `Rng` algorithm currently available in Rust without
@@ -1099,13 +1169,13 @@ impl SeedableRng for StdRng {
10991169
/// create the `Rng` yourself.
11001170
///
11011171
/// This will seed the generator with randomness from thread_rng.
1172+
#[deprecated(since="0.5.0", note="removed in favor of SmallRng")]
11021173
#[cfg(feature="std")]
11031174
pub fn weak_rng() -> XorShiftRng {
11041175
XorShiftRng::from_rng(&mut thread_rng()).unwrap_or_else(|err|
11051176
panic!("weak_rng failed: {:?}", err))
11061177
}
11071178

1108-
11091179
/// DEPRECATED: use `seq::sample_iter` instead.
11101180
///
11111181
/// Randomly sample up to `amount` elements from a finite iterator.

src/thread_rng.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
use std::cell::RefCell;
1414
use std::rc::Rc;
1515

16-
use {RngCore, CryptoRng, StdRng, SeedableRng, EntropyRng};
17-
use {Distribution, Uniform, Rng, Error};
16+
use {RngCore, CryptoRng, StdRng, SeedableRng, EntropyRng, Error};
17+
use {Distribution, Rng, Uniform};
1818
use reseeding::ReseedingRng;
1919

2020
// Number of generated bytes after which to reseed `TreadRng`.
@@ -99,8 +99,10 @@ impl RngCore for ThreadRng {
9999

100100
impl CryptoRng for ThreadRng {}
101101

102+
/// DEPRECATED: use `thread_rng().gen()` instead.
103+
///
102104
/// Generates a random value using the thread-local random number generator.
103-
///
105+
///
104106
/// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
105107
/// documentation of the entropy source and [`Rand`] for documentation of
106108
/// distributions and type-specific generation.
@@ -139,17 +141,18 @@ impl CryptoRng for ThreadRng {}
139141
/// *x = rng.gen();
140142
/// }
141143
/// ```
142-
///
144+
///
143145
/// [`thread_rng`]: fn.thread_rng.html
144146
/// [`Rand`]: trait.Rand.html
147+
#[deprecated(since="0.5.0", note="removed in favor of thread_rng().gen()")]
145148
#[inline]
146149
pub fn random<T>() -> T where Uniform: Distribution<T> {
147150
thread_rng().gen()
148151
}
149152

150153
#[cfg(test)]
151154
mod test {
152-
use super::*;
155+
use Rng;
153156

154157
#[test]
155158
#[cfg(feature="std")]
@@ -165,7 +168,9 @@ mod test {
165168
}
166169

167170
#[test]
171+
#[allow(deprecated)]
168172
fn test_random() {
173+
use super::random;
169174
// not sure how to test this aside from just getting some values
170175
let _n : usize = random();
171176
let _f : f32 = random();

0 commit comments

Comments
 (0)