Hacker News new | ask | show | jobs
by cyber_kinetist 1080 days ago
Rust’s print function locks by default (because of safety), C doesn’t. For more info see the Rust documentation: https://doc.rust-lang.org/std/macro.print.html

In order to get similar performance as C, you probably need to take care of this lock yourself:

    let mut lock = stdout().lock();
    write!(lock, "hello world").unwrap();
(And also you need to make the buffering size for stdout match C’s.)
2 comments

> Rust’s print function locks by default (because of safety), C doesn’t.

Huh? Traditionally, stdio implementations have placed locks around all I/O[1] when introducing threads—thus functions such as fputc_unlocked to claw back at least some of the performance when the stock bulk functions don’t suffice—and the current ISO C standard even requires it (N3096 7.23.2p8):

> All functions that read, write, position, or query the position of a stream lock the stream before accessing it. They release the lock associated with the stream when the access is complete.

The Microsoft C runtime used to have a statically linked non-threaded version with no locks, but it no longer does. (I’ve always assumed that linking -lpthread as required on some Unices was also intended to override some of the -lc code with thread-safe versions, but I’m not sure; in any case this doesn’t play well with dynamic linking, and Glibc doesn’t do it that way.)

[1] e.g. see https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iofpu...

Thanks for the correction, I wasn't aware that the latest C11 standard made these functions thread-safe in the spec. (And as you've said implementations like glibc already have these locks)
Take a look at the actual implementation on stackexchange, the slower impl is already doing the locking itself.