Difference between array vs. vec for memory and cpu usage


#1

If I have something like this:

impl Foo {
  pub fn render(self:&Self) {
    let scratch_matrix_array:[f32;16] = [0.0;16];
    let scratch_matrix_vec:Vec<f32> = vec![0.0;16];
    ...
  }
}

Am I understanding correctly that the following tradeoffs exist?

  1. scratch_matrix_array will persist for each instance of Foo and there is no additional allocation per render() call. It simply lives on the stack and does not get de-allocated until that instance of Foo is dropped. However, there’s potential danger in large memory usage because each new instance of Foo will allocate a new scratch_matrix_array

  2. scratch_matrix_vec will be re-allocated at the start of each render() and dropped at the end. Therefore the net usage of memory is very low. However, there is CPU overhead due to this process on each render() call


#2

I’m pretty sure that unless you specify that you want to store scratch_matrix_array in self, it’ll be dropped at the end of the function call:
Playground
Remember that a big thing in rust is ownership, which specifies that everything the function owns will be dropped when it’s done executing (Which includes references, but not the values they point to)


#3

Oh interesting… thanks for clarifying that!

So for a use case like this, it would probably be better to use an Array since it’s faster to allocate/drop and it will have the same overall memory usage as a Vec?


#4

Well if it’s of fixed size, then sure, otherwise you’d be better off using a Vec, note also that many functions don’t take a fixed-size array because of how non-portable it is


#5

In your case the fixed array is allocated temporarily on the stack, which is a bit faster, but less flexible, as stack location can’t outlive the function, so the array has to be destroyed or copied elsewhere. Copying of fixed-size arrays is more expensive than moving of a Vec.

Fixed size arrays can’t be empty at any time, so when you crate them, you immediately have to initialize them. Often it means you initialize them twice, once with a zero/default value, and second time with some computed one.

Because Rust doesn’t have const generics yet, fixed sized arrays have usability issues, especially above 32 elements.


#7

Move does not call drop.


#8

Moving just copies the raw bytes of the object. I’m the case of a Vec this means copying a pointer and two integers (the length and capacity). In the case of an array it means copying the entire array. But for a temporary you presumably won’t want to move it and thus this won’t be relevant.