I'm trying to encode protobuf to Vec without protobuf's encoding method to make more compression and to easy access the required part without deserializing everything.
Looks like my code is not performant as protobuf serialization.
You have Vec's .extend_from_slice() at your disposal if you want to ensure it boils down to (a potential .reserve(enough) setup call, followed by) a memcpy.
In practice, I don't think it will change much, since Vec uses specialization to have .extend() be .extend_from_slice() when the given iterator is a slice::Iter, but this is a brittle / implementation-specific optimization, whereas .extend_from_slice() guarantees it.
.copy_from_slice() is a method on slices, not necessarily Vecs. It allows overwriting a buffer with a copy from another one. You can use it to write stuff into the already initialized / filled part of a Vec, but that also kind of defeats the purpose of using a Vec to begin with. The main point of a Vec is its being able to grow if / as needed, which .extend_from_slice() does.
If you want access to more fine-grained operations on the initialized and non-initialized parts of a Vec, then I recommend you use ::uninit::prelude::VecCapacity utilities:
use ::uninit::prelude::*;
let buf: &[u8] = attribute_size.to_be_bytes();
vec.reserve_uninit(buf.len()).copy_from_slice(buf);
unsafe { vec.set_len(vec.len() + buf.len()); }
// the previous two lines are equivalent to `.extend_from_slice(buf)`