I am trying to implement deserialization into Rc<[u8]>
without double allocating. The solutions I saw always creates an intermediate Vec<u8>
and filling it in, and then converting it to an Rc
. But this causes double allocation, first when filling in the Vec<u8>
, and second converting it into Rc<[u8]>
.
Is there a way to directly allocate N bytes (N is read from the deserialization reader) into Rc<[u8]>
, and using the buffer as input to the reader? I am OK to unsafe usage as long as there are no memory leaks.
This can be accomplished in safe code, by using Rc::from_iter
with a TrustedLen
iterator:
Iterators of known length
When your
Iterator
implementsTrustedLen
and is of an exact size, a single allocation will be made for theRc<[T]>
. For example:
use std::rc::Rc;
pub fn rc_slice<T: Default>(n: usize) -> Rc<[T]> {
Rc::from_iter((0..n).map(|_| T::default()))
}
fn main() {
let mut data = rc_slice::<u8>(16);
// TODO: ovewrite contents of `data` with deserialized data
*Rc::get_mut(&mut data).unwrap()[0] = ...;
}
Note: This solution relies on a zero/Default
initialization of the Rc
contents prior to deserialization, which works for u8
. If this isn't available for your type, consider using unsafe
to allocate an uninitialized Rc
-slice.