Println!() vs write!() + std::io::stdout().lock()

Context: figuring out the less-than-obvious parts of std.


Getting some mixed results from the use of println!(...) macro vs manual locking of the std::io::stdout() before calling the write!(...) on the lock() of the Stdout itself.

Sample code is here.

Question: how come the playground's execution is on the order of a few ms - regardless of whether it's a Debug or Release mode, while on my own local Win10 the println!() easily takes around 100+ ms, with the write!() into the StdoutLock<'_> is taking 1.25x to 1.5x+ as much?

That last bit is particularly surprising. Shouldn't println!() always be slower?

from my terminal
println!: 95.6391ms / 1000 lines -> 95.639µs / line
lock + write!: 149.5469ms / 1000 lines -> 149.546µs / line

in this example, both println!(...) and write!(locked, ...) will flush the file descriptor because of the newline character, and the locking overhead is negligible compared to the write system call: on low contention situations, the locking operation is just a couple of atomic operation in user space and is especially cheap (relative to non-atomic oeprations) on x86 archtecture.

so the difference you measured between println!() and write!(locked) is just noise.

on the other hand, the difference between Windows and Linux (the playground's backend runs in docker containers) is very real, but not surprising at all, since Windows console IO is notoriously slow. you can find plenty of writings if you google keywords likc "windows console slow". see e.g. Casey's refterm project and his words on the problem.

4 Likes