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_box
es 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
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!
black_box
is a useful tip