192 bytes: V or Rc<V>

I have a cache of the form:

A: RefCell<HashMap<K, V>>
B: RefCell<HashMap<K, Rc<V>>>

V here is 192 bytes.

Because of the RefCell, we can't return a &, (though we can return a Borrow ... but that becomes messy).

Choice A: we have to copy 192 bytes.

Choice B: We have to clone a Rc (but extra level of indirection); this is (?) 4 bytes on wasm32 ?

Is there an obvious right solution here? Both seems slightly optimal, 192 bytes = 3 cache lines; Rc approach = extra level of indirection.

Why not return a Ref<'_, V>?

1 Like

If you have to choose between these two, using RC would be the right choice most of the time, the indirection is not that impactful.
You can always benchmark it though.

1 Like

I believe a Ref<...> would require an immutable borrow of the RefCell<...>. This means, if, while we are holding the Ref, we do another piece of work which mutates the RefCell (say adding another entry into the cache), this would be a runtime panic.

A concrete way this can happen is:

let t: Vec<Key>;
let mut out = vec![];

for x in t  {
  out.push(cache.get(x));
}

if we have an impl of get that is "if it exists, return old value; if not, calc new value, cache it, and return it", then this can result in a runtime error of "holding on to a Ref; while we try to insert a new item into the cache"

[I do concede none of this was in the original question.]