diff --git a/CHANGELOG.md b/CHANGELOG.md index 32919ded61..56579821c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update. - Rename `Rng::gen_range` to `random_range`, `gen_bool` to `random_bool`, `gen_ratio` to `random_ratio` (#1505) - Rename `Standard` to `StandardUniform` (#1526) - Remove impl of `Distribution>` for `Standard` (#1526) +- Remove `SmallRng::from_thread_rng` (#1532) - Remove first parameter (`rng`) of `ReseedingRng::new` (#1533) ## [0.9.0-alpha.1] - 2024-03-18 diff --git a/benches/benches/distr.rs b/benches/benches/distr.rs index ec43e7e61c..94a3940443 100644 --- a/benches/benches/distr.rs +++ b/benches/benches/distr.rs @@ -25,7 +25,7 @@ const ITER_ELTS: u64 = 100; macro_rules! distr_int { ($group:ident, $fnn:expr, $ty:ty, $distr:expr) => { $group.bench_function($fnn, |c| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let distr = $distr; c.iter(|| distr.sample(&mut rng)); @@ -36,7 +36,7 @@ macro_rules! distr_int { macro_rules! distr_float { ($group:ident, $fnn:expr, $ty:ty, $distr:expr) => { $group.bench_function($fnn, |c| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let distr = $distr; c.iter(|| Distribution::<$ty>::sample(&distr, &mut rng)); @@ -47,7 +47,7 @@ macro_rules! distr_float { macro_rules! distr_arr { ($group:ident, $fnn:expr, $ty:ty, $distr:expr) => { $group.bench_function($fnn, |c| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let distr = $distr; c.iter(|| Distribution::<$ty>::sample(&distr, &mut rng)); @@ -76,7 +76,7 @@ fn bench(c: &mut Criterion) { g.throughput(Throughput::Elements(ITER_ELTS)); g.bench_function("iter", |c| { use core::f64::consts::{E, PI}; - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let distr = Normal::new(-E, PI).unwrap(); c.iter(|| { @@ -145,7 +145,7 @@ fn bench(c: &mut Criterion) { } g.throughput(Throughput::Elements(ITER_ELTS)); g.bench_function("variable", |c| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let ldistr = Uniform::new(0.1, 10.0).unwrap(); c.iter(|| { @@ -165,7 +165,7 @@ fn bench(c: &mut Criterion) { let mut g = c.benchmark_group("bernoulli"); g.bench_function("bernoulli", |c| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); let distr = Bernoulli::new(0.18).unwrap(); c.iter(|| distr.sample(&mut rng)) }); diff --git a/benches/benches/generators.rs b/benches/benches/generators.rs index 5c98d37ef6..64325ceb9e 100644 --- a/benches/benches/generators.rs +++ b/benches/benches/generators.rs @@ -40,15 +40,15 @@ pub fn random_bytes(c: &mut Criterion) { } bench(&mut g, "step", StepRng::new(0, 1)); - bench(&mut g, "pcg32", Pcg32::from_os_rng()); - bench(&mut g, "pcg64", Pcg64::from_os_rng()); - bench(&mut g, "pcg64mcg", Pcg64Mcg::from_os_rng()); - bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_os_rng()); - bench(&mut g, "chacha8", ChaCha8Rng::from_os_rng()); - bench(&mut g, "chacha12", ChaCha12Rng::from_os_rng()); - bench(&mut g, "chacha20", ChaCha20Rng::from_os_rng()); - bench(&mut g, "std", StdRng::from_os_rng()); - bench(&mut g, "small", SmallRng::from_thread_rng()); + bench(&mut g, "pcg32", Pcg32::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64", Pcg64::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64mcg", Pcg64Mcg::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_rng(&mut rand::rng())); + bench(&mut g, "chacha8", ChaCha8Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha12", ChaCha12Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha20", ChaCha20Rng::from_rng(&mut rand::rng())); + bench(&mut g, "std", StdRng::from_rng(&mut rand::rng())); + bench(&mut g, "small", SmallRng::from_rng(&mut rand::rng())); bench(&mut g, "os", UnwrapErr(OsRng)); bench(&mut g, "thread", rand::rng()); @@ -69,15 +69,15 @@ pub fn random_u32(c: &mut Criterion) { } bench(&mut g, "step", StepRng::new(0, 1)); - bench(&mut g, "pcg32", Pcg32::from_os_rng()); - bench(&mut g, "pcg64", Pcg64::from_os_rng()); - bench(&mut g, "pcg64mcg", Pcg64Mcg::from_os_rng()); - bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_os_rng()); - bench(&mut g, "chacha8", ChaCha8Rng::from_os_rng()); - bench(&mut g, "chacha12", ChaCha12Rng::from_os_rng()); - bench(&mut g, "chacha20", ChaCha20Rng::from_os_rng()); - bench(&mut g, "std", StdRng::from_os_rng()); - bench(&mut g, "small", SmallRng::from_thread_rng()); + bench(&mut g, "pcg32", Pcg32::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64", Pcg64::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64mcg", Pcg64Mcg::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_rng(&mut rand::rng())); + bench(&mut g, "chacha8", ChaCha8Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha12", ChaCha12Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha20", ChaCha20Rng::from_rng(&mut rand::rng())); + bench(&mut g, "std", StdRng::from_rng(&mut rand::rng())); + bench(&mut g, "small", SmallRng::from_rng(&mut rand::rng())); bench(&mut g, "os", UnwrapErr(OsRng)); bench(&mut g, "thread", rand::rng()); @@ -98,15 +98,15 @@ pub fn random_u64(c: &mut Criterion) { } bench(&mut g, "step", StepRng::new(0, 1)); - bench(&mut g, "pcg32", Pcg32::from_os_rng()); - bench(&mut g, "pcg64", Pcg64::from_os_rng()); - bench(&mut g, "pcg64mcg", Pcg64Mcg::from_os_rng()); - bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_os_rng()); - bench(&mut g, "chacha8", ChaCha8Rng::from_os_rng()); - bench(&mut g, "chacha12", ChaCha12Rng::from_os_rng()); - bench(&mut g, "chacha20", ChaCha20Rng::from_os_rng()); - bench(&mut g, "std", StdRng::from_os_rng()); - bench(&mut g, "small", SmallRng::from_thread_rng()); + bench(&mut g, "pcg32", Pcg32::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64", Pcg64::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64mcg", Pcg64Mcg::from_rng(&mut rand::rng())); + bench(&mut g, "pcg64dxsm", Pcg64Dxsm::from_rng(&mut rand::rng())); + bench(&mut g, "chacha8", ChaCha8Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha12", ChaCha12Rng::from_rng(&mut rand::rng())); + bench(&mut g, "chacha20", ChaCha20Rng::from_rng(&mut rand::rng())); + bench(&mut g, "std", StdRng::from_rng(&mut rand::rng())); + bench(&mut g, "small", SmallRng::from_rng(&mut rand::rng())); bench(&mut g, "os", UnwrapErr(OsRng)); bench(&mut g, "thread", rand::rng()); @@ -120,7 +120,7 @@ pub fn init_gen(c: &mut Criterion) { fn bench(g: &mut BenchmarkGroup, name: &str) { g.bench_function(name, |b| { - let mut rng = Pcg32::from_os_rng(); + let mut rng = Pcg32::from_rng(&mut rand::rng()); b.iter(|| R::from_rng(&mut rng)); }); } @@ -145,7 +145,7 @@ pub fn init_from_u64(c: &mut Criterion) { fn bench(g: &mut BenchmarkGroup, name: &str) { g.bench_function(name, |b| { - let mut rng = Pcg32::from_os_rng(); + let mut rng = Pcg32::from_rng(&mut rand::rng()); let seed = rng.random(); b.iter(|| R::seed_from_u64(black_box(seed))); }); @@ -174,7 +174,7 @@ pub fn init_from_seed(c: &mut Criterion) { rand::distr::StandardUniform: Distribution<::Seed>, { g.bench_function(name, |b| { - let mut rng = Pcg32::from_os_rng(); + let mut rng = Pcg32::from_rng(&mut rand::rng()); let seed = rng.random(); b.iter(|| R::from_seed(black_box(seed.clone()))); }); diff --git a/benches/benches/standard.rs b/benches/benches/standard.rs index ffe7ea5de1..ac38f0225f 100644 --- a/benches/benches/standard.rs +++ b/benches/benches/standard.rs @@ -27,7 +27,7 @@ where { g.throughput(criterion::Throughput::Bytes(size_of::() as u64)); g.bench_function(name, |b| { - let mut rng = Pcg64Mcg::from_os_rng(); + let mut rng = Pcg64Mcg::from_rng(&mut rand::rng()); b.iter(|| rng.sample::(D::default())); }); diff --git a/rand_chacha/src/lib.rs b/rand_chacha/src/lib.rs index e7a3d25eb1..24ddd601d2 100644 --- a/rand_chacha/src/lib.rs +++ b/rand_chacha/src/lib.rs @@ -46,6 +46,9 @@ //! or a deterministic generator such as [`ChaCha20Rng`]. //! Beware that should a weak master generator be used, correlations may be //! detectable between the outputs of its child generators. +//! ```ignore +//! let rng = ChaCha12Rng::from_rng(&mut rand::rng()); +//! ``` //! //! See also [Seeding RNGs] in the book. //! diff --git a/rand_pcg/src/lib.rs b/rand_pcg/src/lib.rs index 3ea401debf..6b9d9d833f 100644 --- a/rand_pcg/src/lib.rs +++ b/rand_pcg/src/lib.rs @@ -34,24 +34,21 @@ //! Generators implement the [`SeedableRng`] trait. All methods are suitable for //! seeding. Some suggestions: //! -//! 1. Seed **from an integer** via `seed_from_u64`. This uses a hash function -//! internally to yield a (typically) good seed from any input. -//! ``` -//! # use {rand_core::SeedableRng, rand_pcg::Pcg64Mcg}; -//! let rng = Pcg64Mcg::seed_from_u64(1); +//! 1. To automatically seed with a unique seed, use [`SeedableRng::from_rng`] +//! with a master generator (here [`rand::rng()`](https://docs.rs/rand/latest/rand/fn.rng.html)): +//! ```ignore +//! use rand_core::SeedableRng; +//! use rand_pcg::Pcg64Mcg; +//! let rng = Pcg64Mcg::from_rng(&mut rand::rng()); //! # let _: Pcg64Mcg = rng; //! ``` -//! 2. With a fresh seed, **direct from the OS** (implies a syscall): +//! 2. Seed **from an integer** via `seed_from_u64`. This uses a hash function +//! internally to yield a (typically) good seed from any input. //! ``` //! # use {rand_core::SeedableRng, rand_pcg::Pcg64Mcg}; -//! let rng = Pcg64Mcg::from_os_rng(); +//! let rng = Pcg64Mcg::seed_from_u64(1); //! # let _: Pcg64Mcg = rng; //! ``` -//! 3. **From a master generator.** This could be [`rand::rng`] -//! (effectively a fresh seed without the need for a syscall on each usage) -//! or a deterministic generator such as [`rand_chacha::ChaCha8Rng`]. -//! Beware that should a weak master generator be used, correlations may be -//! detectable between the outputs of its child generators. //! //! See also [Seeding RNGs] in the book. //! @@ -77,6 +74,7 @@ //! [Random Values]: https://rust-random.github.io/book/guide-values.html //! [`RngCore`]: rand_core::RngCore //! [`SeedableRng`]: rand_core::SeedableRng +//! [`SeedableRng::from_rng`]: rand_core::SeedableRng#method.from_rng //! [`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html //! [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html //! [`rand_chacha::ChaCha8Rng`]: https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha8Rng.html diff --git a/src/distr/mod.rs b/src/distr/mod.rs index 9ee932417f..84bf4925a2 100644 --- a/src/distr/mod.rs +++ b/src/distr/mod.rs @@ -182,7 +182,7 @@ use crate::Rng; /// use rand::prelude::*; /// use rand::distr::StandardUniform; /// -/// let val: f32 = StdRng::from_os_rng().sample(StandardUniform); +/// let val: f32 = rand::rng().sample(StandardUniform); /// println!("f32 from [0, 1): {}", val); /// ``` /// diff --git a/src/rngs/small.rs b/src/rngs/small.rs index 1f9e7f5b8c..67e0d0544f 100644 --- a/src/rngs/small.rs +++ b/src/rngs/small.rs @@ -40,24 +40,29 @@ type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus; /// suitable for seeding, but note that, even with a fixed seed, output is not /// [portable]. Some suggestions: /// -/// 1. Seed **from an integer** via `seed_from_u64`. This uses a hash function -/// internally to yield a (typically) good seed from any input. +/// 1. To automatically seed with a unique seed, use [`SeedableRng::from_rng`]: /// ``` -/// # use rand::{SeedableRng, rngs::SmallRng}; -/// let rng = SmallRng::seed_from_u64(1); +/// use rand::SeedableRng; +/// use rand::rngs::SmallRng; +/// let rng = SmallRng::from_rng(&mut rand::rng()); /// # let _: SmallRng = rng; /// ``` -/// 2. With a fresh seed, **direct from the OS** (implies a syscall): +/// or [`SeedableRng::from_os_rng`]: /// ``` -/// # use rand::{SeedableRng, rngs::SmallRng}; +/// # use rand::SeedableRng; +/// # use rand::rngs::SmallRng; /// let rng = SmallRng::from_os_rng(); /// # let _: SmallRng = rng; /// ``` -/// 3. Via [`SmallRng::from_thread_rng`]: +/// 2. To use a deterministic integral seed, use `seed_from_u64`. This uses a +/// hash function internally to yield a (typically) good seed from any +/// input. /// ``` -/// # use rand::rngs::SmallRng; -/// let rng = SmallRng::from_thread_rng(); +/// # use rand::{SeedableRng, rngs::SmallRng}; +/// let rng = SmallRng::seed_from_u64(1); +/// # let _: SmallRng = rng; /// ``` +/// 3. To seed deterministically from text or other input, use [`rand_seeder`]. /// /// See also [Seeding RNGs] in the book. /// @@ -74,6 +79,7 @@ type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus; /// [rand_pcg]: https://crates.io/crates/rand_pcg /// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro /// [`rand_chacha::ChaCha8Rng`]: https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha8Rng.html +/// [`rand_seeder`]: https://docs.rs/rand_seeder/latest/rand_seeder/ #[derive(Clone, Debug, PartialEq, Eq)] pub struct SmallRng(Rng); @@ -112,19 +118,3 @@ impl RngCore for SmallRng { self.0.fill_bytes(dest) } } - -impl SmallRng { - /// Construct an instance seeded from `rand::rng` - /// - /// # Panics - /// - /// This method panics only if [`crate::rng()`] fails to - /// initialize. - #[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))] - #[inline(always)] - pub fn from_thread_rng() -> Self { - let mut seed = ::Seed::default(); - crate::rng().fill_bytes(seed.as_mut()); - SmallRng(Rng::from_seed(seed)) - } -} diff --git a/src/rngs/std.rs b/src/rngs/std.rs index d59291b856..fd2c24e30a 100644 --- a/src/rngs/std.rs +++ b/src/rngs/std.rs @@ -37,15 +37,22 @@ use rand_chacha::ChaCha12Rng as Rng; /// but note that `seed_from_u64` is not suitable for usage where security is /// important. Also note that, even with a fixed seed, output is not [portable]. /// -/// It is suggested to use a fresh seed **direct from the OS** as the most -/// secure and convenient option: +/// Using a fresh seed **direct from the OS** is the most secure option: /// ``` /// # use rand::{SeedableRng, rngs::StdRng}; /// let rng = StdRng::from_os_rng(); /// # let _: StdRng = rng; /// ``` /// -/// See also [Seeding RNGs] in the book. +/// Seeding via [`rand::rng()`](crate::rng()) may be faster: +/// ``` +/// # use rand::{SeedableRng, rngs::StdRng}; +/// let rng = StdRng::from_rng(&mut rand::rng()); +/// # let _: StdRng = rng; +/// ``` +/// +/// Any [`SeedableRng`] method may be used, but note that `seed_from_u64` is not +/// suitable where security is required. See also [Seeding RNGs] in the book. /// /// ## Generation ///