I have a question regarding the Arc in Rust. I want to do something with multi-threading and stumbled on Arcs to give multiple threads access to the same data. At the moment, I use a struct with the fields being Arcs, and the struct is just normal. I use the struct as some kind of configuration and give the function that needs it a clone to the needed field. My question is, would it be better practice to make the struct variable an arc and the fields normal than give it to the function and retrieve the needed fields? I'm very interested in the memory usage and speed differences; are there any, or is it just convenience to use one or the other?
Code I think of:
struct Config{
name: String,
id: u32,
...
}
let myconf = Arc::new(Config::default());
do_stuff(myconf.clone()).await;
...
current code:
struct Config{
name: Arc<String>,
id: Arc<u32>,
...
}
let myconf = Config::default();
do_stuff(myconf.name.clone(), myconf.id.clone()).await;
...
If all fields are
Arc, it is usually better to hold the entire struct behind anArcinstead of just manyArcs for each field.This way, cloning and drops are cheaper (just one reference count bump instead of many), moving the struct around is cheaper (just one pointer instead of many), struct creation is faster (one allocation instead of many), less memory is used (because each
Arcrequires two additional words for the reference count), and cache locality is better (since the data is in contiguous allocation instead of scattered in many), and there is also less pointer chasing.If you want to hide the fact that an
Arcis used from the interface, you can have two structs,ConfigandConfigInner, and letConfigbe just a wrapper aroundArc<ConfigInner>.