mardi 1 septembre 2020

Random string generator with minimal allocations

I want to generate a large file of pseudo-random ASCII characters given the parameters: size per line and number of lines. I cannot figure out a way to do this without allocating new Strings for each line. This is what I have: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=42f5b803910e3a15ff20561117bf9176

use rand::{Rng, SeedableRng};
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let mut data: Vec<u8> = Vec::new();
    write_random_lines(&mut data, 10, 10)?;
    println!("{}", std::str::from_utf8(&data)?);
    Ok(())
}

fn write_random_lines<W>(
    file: &mut W,
    line_size: usize,
    line_count: usize,
) -> Result<(), Box<dyn Error>>
where
    W: std::io::Write,
{
    for _ in 0..line_count {
        let mut s: String = rand::rngs::SmallRng::from_entropy()
            .sample_iter(rand::distributions::Alphanumeric)
            .take(line_size)
            .collect();
        s.push('\n');
        file.write(s.as_bytes())?;
    }
    Ok(())
}

I'm creating a new String every line, so I believe this is not memory efficient. There is fn fill_bytes(&mut self, dest: &mut [u8]) but this is for bytes.

I would preferably not create a new SmallRng for each line, but it is used in a loop and SmallRng cannot be copied.

How can I generate a random file in a more memory and time efficient way?




Aucun commentaire:

Enregistrer un commentaire