Hey there. There is this relatively new thing in Rust that is called MaybeUninit.
Basically it could help saving a couple of bucks reading data from stable memory. Can we get that in ic-cdk-rs? I can’t find a way to use it currently, since stable_read only accepts &mut [u8] as an argument.
Could you elaborate about what you want to achieve?
IIUC, MaybeUninit is used in unsafe code. While the stable memory module is a safe abstract over system API which implemented standard Read/Write traits. So it’s unlikely to incorporate MaybeUninit with stable memory.
When you read from stable memory, you do something like this:
let mut buf = vec![0u8; size];
stable_read(offset, &mut buf);
You create a buffer (maybe a big one), you initialize it with zeros (sequentially setting every byte to 0) and then you read. This initialization step is a waste of performance, since you are going to rewrite those zeros with the content of stable memory anyway.
This is a known pattern in Rust and MaybeUninit is the tool to solve this problem.
Basically it allows your program to work with uninitialized memory in a type-safe way.
I’m thinking of something like this:
let mut vec = MaybeUninit::new(Vec::<u8>::with_capacity(size));
stable_read_uninit(vec.as_mut_ptr());
P.S.
It is possible to fix this performance inperfection without MaybeUninit, like this
Doubt. Why would the compiler optimize it in such a way? Everything it sees is that someone creates a buffer and gives a mutable pointer to that buffer to some FFI.
What if this FFI does nothing with the buffer and returns it back? The user would end up with an uninitialized buffer, that they were explicitly trying to initialize?
I’m not entirely sure, since I didn’t perform any bitcode inspect, but coming from a simple logic it seems like there should definitely be an initialization step in it.