Skip to content

Commit

Permalink
Optimise .fill() throughput (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bluefinger authored Feb 1, 2023
1 parent 8e91b8d commit 08f7d3c
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()]);
}
}

Expand Down

0 comments on commit 08f7d3c

Please sign in to comment.