When would you want to use a boxed array?

It seems that boxed slices (Box<[T]>) are pretty common but boxed arrays (Box<[T; N]>) are not.

I haven't done an extensive search, but one place I've found this is in the object crate. I don't really understand the code but my impression is that it's kind of using the boxed array like a struct.

Context: I'm working on a guide to contiguous data in Rust. I'm pretty sure boxed arrays are rare enough to not need to mention, but it made me curious what they can be used for!

The primary difference is that arrays are Sized, which lets the box be a thin pointer instead of a fat pointer, halving its stack size. The arrays can also be stored unboxed on the stack or as a structure field, which might help when writing or interacting with generic code.

It also gives you a compile-time guarantee about the number of elements, and the len() call will be const. This can help if the array is being used for something like a radix sort or bloom filter, where the element index is computed in a complicated way. If the array is large enough, passing it around as a Box can be significantly more efficient than by value.

2 Likes
  • Boxed array itself is small, so it can make the containing struct small.
    • struct Direct([HugeStruct; 16]); would be expensive to move, but sturct Indirect(Box<[HugeStruct; 16]>); will be same size as a single pointer (usually 8 bytes).
  • Element access to boxed array will be a little faster than boxed slice, because the compiler knows its size and can do more optimizations.
    • I haven't tested, but theoretically it will be.

Of course, however, boxed array is usually inconvenient because the size should be fixed at compile time.
Boxed array provides stricter limitation than Vec and boxed slice, so it would be usable in fewer situation.
But when you use it, it would give you more guarantee and more performance.

1 Like

I think it comes from technical limitations which make Box<[T; N]> unusable:

  • For most of its existence, Rust had very poor support for arrays longer than 32 elements. Longer arrays are very cumbersome to use without the const generics feature.

  • Box::new(arr) usually ends up with its arguments on the stack, which causes stack overflows for large arrays.

Since large arrays are unusable, and it's usually inefficient to box small arrays (in modern CPUs small copies are cheap, indirection and allocations can be expensive), there's little use for boxed arrays.

7 Likes

Is the static array limitation to 32 elements definitive or could we expect, in the future, to see this constrain disappear ?

I have no idea of what are this const generic feature. A nightly compiler feature ? Do you have a link to its documentation ?

Thanks !

The 32-element limitation is going away. Probably even this year.

Here's the spec:

although not all of it works yet.

Wouaw ! I read the paper two times, and it looks like the subject is much more wide than I expected, wider than my Rust theoretical background :flushed:
However, I have my answer. Thanks.

1 Like