Optimise .fill() throughput (#43)

This commit is contained in:
Gonçalo Rica Pais da Silva 2023-02-01 02:36:41 +01:00 committed by GitHub
parent 8e91b8da49
commit 08f7d3c29f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 7 deletions

View File

@ -444,18 +444,26 @@ impl Rng {
}
/// Fill a byte slice with random data.
#[inline]
pub fn fill(&self, slice: &mut [u8]) {
// Filling the buffer in chunks of 8 is much faster.
let mut chunks = slice.chunks_exact_mut(8);
// We fill the slice by chunks of 8 bytes, or one block of
// WyRand output per new state.
let mut chunks = slice.chunks_exact_mut(core::mem::size_of::<u64>());
for chunk in chunks.by_ref() {
let n = self.gen_u64();
let n = self.gen_u64().to_ne_bytes();
// Safe because the chunks are always 8 bytes exactly.
let bytes: &mut [u8; 8] = chunk.try_into().unwrap();
*bytes = n.to_ne_bytes();
chunk.copy_from_slice(&n);
}
for item in chunks.into_remainder() {
*item = self.u8(..);
let remainder = chunks.into_remainder();
// Any remainder will always be less than 8 bytes.
if !remainder.is_empty() {
// Generate one last block of 8 bytes of entropy
let n = self.gen_u64().to_ne_bytes();
// Use the remaining length to copy from block
remainder.copy_from_slice(&n[..remainder.len()]);
}
}