Hacker News new | ask | show | jobs
by burntsushi 3466 days ago
That's not actually true though. You can use an atomic with a relaxed ordering. For example: https://is.gd/M1Q3Bu

Now, to be fair, this is only one example and I'm sure you could come up with a better one. But this isn't especially controversial. Rust's entire standard library is living proof that you need unsafe to do some things efficiently. The value proposition is that such things can be bundled up behind an abstraction barrier.

In sum, I think "the borrow checker forces runtime overhead" is an incomplete picture. I think a better picture is, "if you completely ban explicit use of unsafe from your code, then you may miss out on some optimization opportunities." i.e., When the borrow checker fails you, you're given a choice: 1) accept safety and the possible performance loss or 2) accept the onus of proving safety and do the fastest thing possible.

I think the fact that those choices are available is an excellent thing. I choose (1) all the time because not every line of code is relevant to performance. But sometimes I get to choose (2), and I'm thankful that such a choice is always very explicit.

For good measure, here's the unsafe version without atomics: https://is.gd/V1K6nD

2 comments

Thread locals are thread local, so you don't need AtomicUsize, you just need a Cell, which has zero overhead.

https://is.gd/c0iCz6

Edit: Zero overhead as compared to C, that is. Cell has a slight overhead in Rust because it prevents certain optimizations that aren't the default in C.

Derp. Thanks for that correction. :-)
Why is a thread local variable atomic?
Because an atomic provides interior mutability for `usize`.

(It's a hack that plays on the GP's specific example of a counter. It doesn't generalize arbitrarily to removing use of RefCell for thread locals in safe code.)