I wrote a program to simply increment a counter and display it in the terminal window:
use std::thread;
use std::time;
fn main() {
let mut bun: u64 = 0;
loop {
print!("\r{}", bun);
bun += 1;
thread::sleep(time::Duration::from_millis(100));
}
}
I thought this was pretty straight-forward (expecting to see the counter incrementing at ~10 times per second) but every time I compile and run it, what I get is the following:
It seems pretty clear to me that the counter is incrementing properly, but that the print! macro is only being called (or working) every 28 or so seconds.
On a hunch I tried eprint!
in place of print!
and this ends up working exactly as I would/did expect originally (i.e. the terminal displays the counter incrementing 10 times per second).
What I can't figure out, then, is why this would work with one and not the other (I was under the impression that printing to io::stderr and io::stdout would be basically the same when using a terminal window). Is there some subtle difference between them that I am not grasping? Is there something else in my code that is causing this that I'm not seeing? I Googled around a bit but couldn't seem to turn up anything relating specifically to this issue.
I am using:
cargo run --release
As mentionned in the documentation for print!, the standard output is line-buffered, which means updates aren't delivered to the terminal after every call. Standard error doesn't seem buffered the same way, so you get immediate updates.
To get the same behaviour on stdout, add a call to std::io::stdout().flush()
after printing.
use std::io::Write;
use std::thread;
use std::time;
fn main() {
let mut bun: u64 = 0;
loop {
print!("\r{}", bun);
std::io::stdout().flush().unwrap();
bun += 1;
thread::sleep(time::Duration::from_millis(100));
}
}