$ python yes.py | pv -r > /dev/null
[11.2MiB/s]
$ python3 yes.py | pv -r > /dev/null
[4.95MiB/s]
As for why the naive rust version is slower, it's because without adding a BufWriter in rust, stdout is line-buffered, so each line emits a write system call, while with python, stdout is buffered. Python 2 emits writes of 4096 bytes, and python 3... 8193 bytes (edit: not a typo, this is 8KiB + 1). That's the likely cause for it being slower.Edit: A minimal version of the naive rust version would be:
fn main() {
loop {
println!("y");
}
}
On the same machine as with the python tests above, I get: $ ./yes | pv -r > /dev/null
[4.81MiB/s]
which is actually as slow as python 3, despite doing 4 thousand times more system calls.A version with buffering would look like:
use std::io::{stdout,BufWriter,Write};
fn main() {
let stdout = stdout();
let mut out = BufWriter::new(stdout.lock());
loop {
writeln!(out, "y").unwrap();
}
}
And produces 129MiB/s on the same machine. And that's strictly doing the same as what the python version does (with a default buffer size of 8KiB, apparently).And fwiw, on the same machine, both GNU yes and the full rust solution from OP do 10.5GiB/s.