DEV Community

Discussion on: Optimizing Immutable Strings in Rust

Collapse
 
jakubdabek profile image
Jakub Dąbek

How did you get to the conclusion that there are only as many bytes allocated by Arc<T> as T takes? That would make it have the same functionality as Box<T>. Just to be extra extra sure, I replicated the code shown in the article (working godbolt here), and I see 2 allocations: 11 bytes for the String data and 40 bytes for the Arc<String>, which contains the 24 for String and 2 AtomicUsizes for strong and weak count.

Interestingly, for Arc<str> there are 32 bytes allocated, because the allocation code aligns to 8 (16 for strong and weak counts, 11 for "Hello World" rounded up to 16).

Apropos note 3., while the From<&str> is interesting, the realest magic happens in copy_from_slice 😉

Other points from the article stand, as there's memory savings to be had and there's rarely any reason to keep immutable strings in String (although there are some niche uses for double indirection e.g. ArcSwap)

Collapse
 
somedood profile image
Basti Ortiz

How did you get to the conclusion that there are only as many bytes allocated by Arc as T takes?

Ah, that is my mistake. I have totally missed that! My original conception of the article came from one of my projects when I realized that I could use a Box<str> over a String. Then, as I wrote this article, I wanted to apply the same optimization over multi-threaded contexts via Arc. It had not occurred to me (until you mentioned it) that Arc actually has some overhead due to atomics, which Box does not have. I had falsely assumed otherwise.

This led to my incorrect conclusion that Arc allocates as Box would. So to make a long story short, I had unintentionally disregarded the Arc overhead, thinking that it was a Box.

Thanks for pointing this out! I shall edit the article accordingly.