我想在给定参数的情况下生成一个大的伪随机 ASCII 字 rune 件:每行大小和行数。如果不为每一行分配新的 String
,我想不出一种方法来做到这一点。这就是我的: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(())
}
我正在每行创建一个新的 String
,所以我认为这不是内存效率高的。有 fn fill_bytes(&mut self, dest: &mut [u8])
但这是针对字节的。
我最好不要为每一行创建一个新的 SmallRng
,但它在循环中使用并且 SmallRng
无法复制。
如何以更节省内存和时间的方式生成随机文件?
最佳答案
您可以轻松地在循环中重用 String
,方法是在循环外创建它并在使用内容后清除
它:
// Use Kevin's suggestion not to make a new `SmallRng` each time:
let mut rng_iter =
rand::rngs::SmallRng::from_entropy().sample_iter(rand::distributions::Alphanumeric);
let mut s = String::with_capacity(line_size + 1); // allocate the buffer
for _ in 0..line_count {
s.extend(rng_iter.by_ref().take(line_size)); // fill the buffer
s.push('\n');
file.write(s.as_bytes())?; // use the contents
s.clear(); // clear the buffer
}
String::clear
删除 String
的内容(必要时删除),但不会释放其后备缓冲区,因此无需重新分配即可重复使用.
另见
关于分配最少的随机字符串生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63697453/