Understanding vec vs boxed slice performance

I have a scenario where I will like to continuously read and write to a fixed sized array (where size is not known at compile time).

As far as I'm aware, this is usually represented as a Box[T]> or Vec<T>, where the main difference between them is the existence of the capacity field and resizing methods on the vec.

I wasn't expecting any significant performance differences, but some example code I wrote seemed to indicate that boxed slices are somehow significantly faster (see playground). How do we explain this behavior?

You must have run in debug mode rather than in release mode. In debug mode there is overhead from function calls not being inlined etc.

And in the release mode all four cycles seem to be optimized out - the result is, like, 30-90 ns. Some strategically placed black_boxes seem to level the results - playground.

4 Likes

where size is not known at compile time

I am sorry, does it really work in Rust?
AFAIK you can't create an array with a size not known at compile time (there are no VLAs in Rust).

In your example you use const. What do I miss?

An there is a one more problem with "array in the box" approach: an array is created on the stack, and then moved (at least in debug mode without any optimizations)

    let v = vec![0; 1024 << 20]; // it works
    let b = Box::new([0u8; 1024 << 20]); // stack overflow
1 Like

But you can create a boxed slice, Box<[T]>, with a size not known at compile time - one example is present in the playground.

2 Likes

True, thanks!

As far as I see, it creates vector under the hood and then converts into into a boxed slice:

#[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
impl<I> FromIterator<I> for Box<[I]> {
    fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
        iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
    }
}

(Sorry for offtopic)

This is abit of a wording issue on my part :slight_smile: what I meant by "fixed sized array" is an area of memory that I don't intend to resize which contains items of the same type. I guess "array" means different things in different languages

In the playground link I sent, only Vec<T> and Box<[T]> are applicable to my use case. I left in [T;N] and Box<[T; N]> for benchmarking purposes

thanks! :smiley: black_box is a useful tip