Designing structs

I was wondering, what the better design for a struct would be.

What I want the record to hold is some data of type B that sits on the heap, and some additional information about it, which is of type A.

Now, the obvious way (in my eyes) would be to do this:

struct X {
    a: A,
    b: Box<B>
}

But here's an alternative that seems to have a clear advantage:

struct Y(Box<(A, B)>)

While it's a little less nice to handle, the advantage I hope for, is that Option could be optimized to only use 64 bits (more precisely: size).

That is because the None case can be represented as a null pointer, a state the Box field can never hold otherwise.

I am very curious to hear your opinions on this.

What's the rust way of doing things?

Have a lovely day!

Do whatever results in the cleanest code downstream.

The performance difference will be negilible unless you are creating millions of these things, and even then you'll gain more performance by using smarter algorithms (e.g. O(log n) instead of O(n2)) or inlining the Box to reduce indirection.

I would write this:

struct X {
    a: A,
    b: B,
}
7 Likes

I'll mention a couple of advantages of this. First and foremost, in the common case where it is passed by reference, there is a single layer of indirection. You can allocate this on the head with a simple Box:: new(X { .. }). And in general is like users of my code to be able to make their own choices about allocation, e.g. they might prefer an Arc or Rc over a Box, and this gives them that flexibility without requiring an additional layer of indirection.

Edit This is also beneficial if the want to use these structs in a collection that is already head allocated like a Vec or a HashMap.

For putting B on the heap, I would suggest

struct X {
    a: A,
    b: Box<B>
}

It's easier to understand, and still does get null-pointer-optimized if you put in an option (playground).
Though I would still suggest @Michael-F-Bryan's suggestion instead.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.