9
9
//! A small fast RNG
10
10
11
11
use rand_core:: { Error , RngCore , SeedableRng } ;
12
+ use crate :: thread_rng;
12
13
13
14
#[ cfg( target_pointer_width = "64" ) ]
14
15
type Rng = super :: xoshiro256plusplus:: Xoshiro256PlusPlus ;
@@ -22,58 +23,20 @@ type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus;
22
23
/// Note that depending on the application, [`StdRng`] may be faster on many
23
24
/// modern platforms while providing higher-quality randomness. Furthermore,
24
25
/// `SmallRng` is **not** a good choice when:
25
- /// - Security against prediction is important. Use [`StdRng`] instead.
26
- /// - Seeds with many zeros are provided. In such cases, it takes `SmallRng`
27
- /// about 10 samples to produce 0 and 1 bits with equal probability. Either
28
- /// provide seeds with an approximately equal number of 0 and 1 (for example
29
- /// by using [`SeedableRng::from_entropy`] or [`SeedableRng::seed_from_u64`]),
30
- /// or use [`StdRng`] instead.
31
26
///
32
- /// The algorithm is deterministic but should not be considered reproducible
33
- /// due to dependence on platform and possible replacement in future
34
- /// library versions. For a reproducible generator, use a named PRNG from an
35
- /// external crate, e.g. [rand_xoshiro] or [rand_chacha] .
36
- /// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html) .
27
+ /// - Portability is required. Its implementation is not fixed. Use a named
28
+ /// generator from an external crate instead, for example [rand_xoshiro] or
29
+ /// [rand_chacha]. Refer also to
30
+ /// [The Book](https://rust-random.github.io/book/guide-rngs.html) .
31
+ /// - Security against prediction is important. Use [`StdRng`] instead .
37
32
///
38
33
/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current
39
34
/// platform, without consideration for cryptography or security. The size of
40
35
/// its state is much smaller than [`StdRng`]. The current algorithm is
41
36
/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit
42
37
/// platforms. Both are also implemented by the [rand_xoshiro] crate.
43
38
///
44
- /// # Examples
45
- ///
46
- /// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
47
- ///
48
- /// ```
49
- /// use rand::{Rng, SeedableRng};
50
- /// use rand::rngs::SmallRng;
51
- ///
52
- /// // Create small, cheap to initialize and fast RNG with a random seed.
53
- /// // The randomness is supplied by the operating system.
54
- /// let mut small_rng = SmallRng::from_entropy();
55
- /// # let v: u32 = small_rng.gen();
56
- /// ```
57
- ///
58
- /// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
59
- /// efficient:
60
- ///
61
- /// ```
62
- /// use rand::{SeedableRng, thread_rng};
63
- /// use rand::rngs::SmallRng;
64
- ///
65
- /// // Create a big, expensive to initialize and slower, but unpredictable RNG.
66
- /// // This is cached and done only once per thread.
67
- /// let mut thread_rng = thread_rng();
68
- /// // Create small, cheap to initialize and fast RNGs with random seeds.
69
- /// // One can generally assume this won't fail.
70
- /// let rngs: Vec<SmallRng> = (0..10)
71
- /// .map(|_| SmallRng::from_rng(&mut thread_rng).unwrap())
72
- /// .collect();
73
- /// ```
74
- ///
75
39
/// [`StdRng`]: crate::rngs::StdRng
76
- /// [`thread_rng`]: crate::thread_rng
77
40
/// [rand_chacha]: https://crates.io/crates/rand_chacha
78
41
/// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro
79
42
#[ cfg_attr( doc_cfg, doc( cfg( feature = "small_rng" ) ) ) ]
@@ -102,21 +65,45 @@ impl RngCore for SmallRng {
102
65
}
103
66
}
104
67
105
- impl SeedableRng for SmallRng {
106
- type Seed = <Rng as SeedableRng >:: Seed ;
107
-
68
+ impl SmallRng {
69
+ /// Construct an instance seeded from another `Rng`
70
+ ///
71
+ /// We recommend that the source (master) RNG uses a different algorithm
72
+ /// (i.e. is not `SmallRng`) to avoid correlations between the child PRNGs.
73
+ ///
74
+ /// # Example
75
+ /// ```
76
+ /// # use rand::rngs::SmallRng;
77
+ /// let rng = SmallRng::from_rng(rand::thread_rng());
78
+ /// ```
108
79
#[ inline( always) ]
109
- fn from_seed ( seed : Self :: Seed ) -> Self {
110
- SmallRng ( Rng :: from_seed ( seed ) )
80
+ pub fn from_rng < R : RngCore > ( rng : R ) -> Result < Self , Error > {
81
+ Rng :: from_rng ( rng ) . map ( SmallRng )
111
82
}
112
83
84
+ /// Construct an instance seeded from the thread-local RNG
113
85
#[ inline( always) ]
114
- fn from_rng < R : RngCore > ( rng : R ) -> Result < Self , Error > {
115
- Rng :: from_rng ( rng ) . map ( SmallRng )
86
+ pub fn from_thread_rng ( ) -> Result < Self , Error > {
87
+ Rng :: from_rng ( thread_rng ( ) ) . map ( SmallRng )
116
88
}
117
89
90
+ /// Construct an instance from a `u64` seed
91
+ ///
92
+ /// This provides a convenient method of seeding a `SmallRng` from a simple
93
+ /// number by use of another algorithm to mutate and expand the input.
94
+ /// This is suitable for use with low Hamming Weight numbers like 0 and 1.
95
+ ///
96
+ /// **Warning:** the implementation is deterministic but not portable:
97
+ /// output values may differ according to platform and may be changed by a
98
+ /// future version of the library.
99
+ ///
100
+ /// # Example
101
+ /// ```
102
+ /// # use rand::rngs::SmallRng;
103
+ /// let rng = SmallRng::seed_from_u64(1);
104
+ /// ```
118
105
#[ inline( always) ]
119
- fn seed_from_u64 ( state : u64 ) -> Self {
106
+ pub fn seed_from_u64 ( state : u64 ) -> Self {
120
107
SmallRng ( Rng :: seed_from_u64 ( state) )
121
108
}
122
109
}
0 commit comments