Arc<String> vs Arc<str>

Hi all,

recently I stubbled upon Arc<String> and Arc<str>. I wonder if there are any pros & conns to use one over the other.

I know String is only a wrapper around Vec<u8> so I guess Arc<String> has an additinal indirection?

Are there any other differences, e.g. regarding clone() performance?

1 Like

Exactly; that's why Arc<str> should be preferred.

Arc<String> is to Arc<str> what Arc<Vec<u8>> is to Arc<[u8]>.

Assuming that you were able to mutate the contents (e.g. by adding a Mutex), the former would allow you to modify the string in a manner that changes its length, whereas the latter would be a fixed-length slice which only allows you to change the value of the inner bytes.

For immutable content, there isn't really a benefit to using Vec<T> over Box<[T]> other than convenience, as the former is easier to create. And the same holds for String vs str.

Furthermore, the latter may actually be slightly more efficient as IIRC you go through one less pointer.

4 Likes
  • Arc<String> adds a layer of indirection (arc -> string length -> text), but it's a thin pointer.
  • Arc<str> removes a layer of indirection (arc & string length -> text), but it's a fat pointer.

So the first one is slower to read, but cheaper to store. But if you need lots of these, you should be using string interning.

1 Like

Another way of seeing this is that Arc<_> is "& _ with a runtime lifetime"; i.e., your question is very similar to

&String vs &str

(forgetting input parameter ergonomics, since they don't work the same with Arc)

then @kornel distinction applies, and usually less indirection should be preferred to smaller pointer size.


Regarding @HadrienG's remark with mutation, there are two cases to consider:

  • Interior Mutability: Arc<RwLock<String>> is clearly "better" than Arc<RwLock<str>>, since there isn't much you can do with a &mut str

  • Memory-sharing with copyclone-on-write mechanics: that's where Arc::make_mut plays a role. Then, again, Arc<String> is to be used instead of Arc<str>


But I find that mutating a String behind an Arc is quite rare, and most often than not Arc<str> or string interning should be used.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.