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

Remove SmallRng::from_thread_rng #1532

Merged
merged 8 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<T>>` for `Standard` (#1526)
- Remove `SmallRng::from_thread_rng` (#1532)

## [0.9.0-alpha.1] - 2024-03-18
- Add the `Slice::num_choices` method to the Slice distribution (#1402)
Expand Down
12 changes: 6 additions & 6 deletions benches/benches/distr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand Down Expand Up @@ -76,7 +76,7 @@ fn bench(c: &mut Criterion<CyclesPerByte>) {
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(|| {
Expand Down Expand Up @@ -145,7 +145,7 @@ fn bench(c: &mut Criterion<CyclesPerByte>) {
}
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(|| {
Expand All @@ -165,7 +165,7 @@ fn bench(c: &mut Criterion<CyclesPerByte>) {

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))
});
Expand Down
62 changes: 31 additions & 31 deletions benches/benches/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand All @@ -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());

Expand All @@ -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());

Expand All @@ -120,7 +120,7 @@ pub fn init_gen(c: &mut Criterion) {

fn bench<R: SeedableRng>(g: &mut BenchmarkGroup<WallTime>, 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));
});
}
Expand All @@ -145,7 +145,7 @@ pub fn init_from_u64(c: &mut Criterion) {

fn bench<R: SeedableRng>(g: &mut BenchmarkGroup<WallTime>, 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)));
});
Expand Down Expand Up @@ -174,7 +174,7 @@ pub fn init_from_seed(c: &mut Criterion) {
rand::distr::StandardUniform: Distribution<<R as SeedableRng>::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())));
});
Expand All @@ -201,7 +201,7 @@ pub fn reseeding_bytes(c: &mut Criterion) {
fn bench(g: &mut BenchmarkGroup<WallTime>, thresh: u64) {
let name = format!("chacha20_{}k", thresh);
g.bench_function(name.as_str(), |b| {
let mut rng = ReseedingRng::new(ChaCha20Core::from_os_rng(), thresh * 1024, OsRng);
let mut rng = ReseedingRng::new(ChaCha20Core::from_rng(&mut rand::rng()), thresh * 1024, OsRng);
let mut buf = [0u8; 1024 * 1024];
b.iter(|| {
rng.fill_bytes(&mut buf);
Expand Down
2 changes: 1 addition & 1 deletion benches/benches/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ where
{
g.throughput(criterion::Throughput::Bytes(size_of::<T>() as u64));
g.bench_function(name, |b| {
let mut rng = Pcg64Mcg::from_os_rng();
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of from_os_rng should not influence the benchmark results since only time for the closure passed to iter is measured.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. It may improve set-up time slightly; at any rate I see no harm in using rand::rng().


b.iter(|| rng.sample::<T, _>(D::default()));
});
Expand Down
3 changes: 3 additions & 0 deletions rand_chacha/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//!
Expand Down
22 changes: 10 additions & 12 deletions rand_pcg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//!
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/distr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
/// ```
///
Expand Down
37 changes: 10 additions & 27 deletions src/rngs/small.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,22 @@ 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):
/// 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::{SeedableRng, rngs::SmallRng};
/// let rng = SmallRng::from_os_rng();
/// let rng = SmallRng::seed_from_u64(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can keep the mention of from_os_rng.

/// # let _: SmallRng = rng;
/// ```
/// 3. Via [`SmallRng::from_thread_rng`]:
/// ```
/// # use rand::rngs::SmallRng;
/// let rng = SmallRng::from_thread_rng();
/// ```
/// 3. To seed deterministically from text or other input, use [`rand_seeder`].
///
/// See also [Seeding RNGs] in the book.
///
Expand All @@ -74,6 +72,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);

Expand Down Expand Up @@ -112,19 +111,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 = <Rng as SeedableRng>::Seed::default();
crate::rng().fill_bytes(seed.as_mut());
SmallRng(Rng::from_seed(seed))
}
}
13 changes: 10 additions & 3 deletions src/rngs/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`] 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
///
Expand Down
Loading