38 ms·
Arc::make_mut is really nice and is something we use a bunch in Stylo to safely mutate possibly-shared styles. Across threads.
by Manishearth 9y ago
Arc::make_mut is really nice and is something we use a bunch in Stylo to safely mutate possibly-shared styles. Across threads.
- deleted 9y ago[deleted]
- seeekr 9y agoBut isn't it an anti-pattern to wrap something in an `Arc` when some of your use cases for it are purely single-threaded, and as such you're wasting a certain (potentially very significant) amount of performance on upholding memory visibility and such even when it's not needed? I have only dabbled in Rust, so I may be misunderstanding the implications of Arc and how it is implemented, and how it behaves in the absence of multiple threads. To me it feels a bit like some of the relatively early Java days when even the Standard Library was using `synchronized` (which is of course way worse than `Arc`) in lots of places like StringBuffer (used for String concatenation), just to be safe in case anyone ever wanted to use that code in a multi-threaded context. Only later folks began to realize that maybe that's not such a great idea and that you need to be able to not pay any synchronization costs when you know you're not going to be sharing a data structure across threads.
- masklinn 9y agoThese collections are of somewhat limited use outside of concurrent scenarios, and I don't think you can (currently?) be generic over allocation in Rust. Since these structures need some sort of automatic memory management for structural sharing, you need to use a GC of some sort, having both atomic and non-atomic Rc would require duplicating the entire thing, once with Rc nodes and one with Arc node, for more or less no value. > I may be misunderstanding the implications of Arc and how it is implemented, and how it behaves in the absence of multiple threads All Arc means is that refcounting operations use atomic increment/decrement instead of regular ones.
- seeekr 9y agoSo that means that the synchronization cost would only be paid when making a new copy of the Arc and releasing each of those. Ok, that extends the set of use cases where it's acceptable to use Arc then. Thanks for clarifying. EDIT: wording
- masklinn 9y ago> So that means that the synchronization cost would only be paid when making a new copy of the Arc and releasing each of those. Yes. An interesting note here is that due to Rust's ubiquitous use of references there will be little extraneous refcounting traffic unlike systems like e.g. Python where `a = b` might trigger a refcount increase. I think it was Armin Ronacher (mitsuhiko) who made that observation a few weeks back, possibly on twitter?
- Manishearth 9y ago> But isn't it an anti-pattern to wrap something in an `Arc` when some of your use cases for it are purely single-threaded, and as such you're wasting a certain (potentially very significant) amount of performance on upholding memory visibility and such even when it's not needed? Yes. You have Rc and Rc::make_mut for the single threaded case. Pick what you need. I interpreted the GP comment as talking about the general pattern of make_mut, not Arc::make_mut itself. Stylo's multithreaded, we pick Arc. Singlethreaded systems can get by with Rc, but there are often legit reasons for picking Arc, and it's not that bad a hit.