change --bytes to use block streaming instead of a single alloc->populate->write

master
Avril 4 years ago
parent 9cab3e1b98
commit 683864c727
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,6 +1,6 @@
[package] [package]
name = "rng" name = "rng"
version = "0.2.0" version = "0.2.1"
authors = ["Avril <flanchan@cumallover.me>"] authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018" edition = "2018"
@ -14,3 +14,9 @@ panic = "unwind"
[dependencies] [dependencies]
getrandom = "0.1" getrandom = "0.1"
[features]
# Dynamically allocate and populate all memory needed for `--bytes` at runtime instead of streaming in fixed size blocks.
#
# This can slightly improve total performance for large outputs, at the cost of a proportionally, arbitrary sized memory allocation along with a proportionally increasing wait while the entire area is populated.
bytes-dynamic = []

@ -7,6 +7,8 @@ use getrandom::*;
mod parse; mod parse;
mod r#impl; mod r#impl;
const BYTES_BUFFER_SIZE: usize = 4096;
fn get<T: Default>() -> Result<T, Error> fn get<T: Default>() -> Result<T, Error>
{ {
let mut value: T = Default::default(); let mut value: T = Default::default();
@ -154,19 +156,37 @@ fn bytes(args: &[String]) -> Result<(), Error>
usage(); usage();
} else { } else {
let num = parse::bytes(&args[0]).expect("Failed to parse number of bytes") as usize; let num = parse::bytes(&args[0]).expect("Failed to parse number of bytes") as usize;
let mut mem = Vec::with_capacity(num);
debug_assert_eq!(mem.capacity(), num); if cfg!(feature="bytes-dynamic") {
// SAFETY: populating uninitialised memory with random data. There are no reads to the uninitialised data. let mut mem = Vec::with_capacity(num);
unsafe {
mem.set_len(num); debug_assert_eq!(mem.capacity(), num);
populate(&mut mem[..])?; // SAFETY: populating uninitialised memory with random data. There are no reads to the uninitialised data.
} unsafe {
debug_assert_eq!(num, mem.len()); mem.set_len(num);
populate(&mut mem[..])?;
}
debug_assert_eq!(num, mem.len());
let stdout = std::io::stdout(); let stdout = std::io::stdout();
use std::io::Write;
stdout.lock().write_all(&mem[..]).expect("write error"); use std::io::Write;
stdout.lock().write_all(&mem[..]).expect("write error");
} else {
let mut buffer = [0u8; BYTES_BUFFER_SIZE];
let mut num = num;
let stdout = std::io::stdout();
let mut stdout = stdout.lock();
while num > 0 {
let w = std::cmp::min(num, BYTES_BUFFER_SIZE);
getrandom(&mut buffer[..w])?;
use std::io::Write;
stdout.write_all(&buffer[..w]).expect("write error");
num -= w;
}
}
} }
Ok(()) Ok(())
} }

Loading…
Cancel
Save