Search code examples
rustclonereference-counting

rust clone() vs Rc or Arc?


I'm trying to understand the pros and cons between:

  • using Arc and cloning the Arc (I'm using Something in various places/threads)

vs

  • using Something.clone() (my Something struct only has 1 field which is already cloneable)

Other than measuring and comparing performance results, which I don't think any of the two would be much worse performance wise, I'm trying to understand what's considered "generally better" or "more idiomatic" in rustaceans minds.

If I understand correctly:

  • Arc and cloning: I have 1 Something on the heap (expensive compared to stack) + I'm cloning Arc (expensive compared to Rc.clone but needed if I need to use across threads) so I create/drop N Arcs depending on how many times I clone/drop

vs

  • Something.clone: I create/drop N instances of Something on the stack depending on how many times I clone/drop

in this situation (where "Something" is cheap to create), is there any benefit of wrapping in an Arc vs just cloning it? is any of the two options preferable?


Solution

  • in this situation (where "Something" is cheap to create), is there any benefit of wrapping in an Arc vs just cloning it? is any of the two options preferable?

    If you literally just have an Arc<Something> and you clone that, then probably not. Arc is necessary if you want to share something betwen threads and the ownership is unclear, usually you'd want some sort of lock inside the refcount to allow for modifying the shared item.

    Though there are cases where it can be useful without lock e.g. the inner object can not (because it's really unique) or should not (because it's expensive) be copied and needs to be (immutably) used by multiple threads (so you use an Arc as a way to share a single instance), or it is sometimes copied (and expensive) but generally is not, in which case rather than create eager copies you can make_mut when it's necessary to "split" the Arc but defer extra allocations up to that point.