Did you, uh, do the thing I can't ask if you did on HN? Because it's entirely about how to get better performance than sentinel values by specially structuring your discriminant.
ORIGINAL:
Not sure what you mean, so I'll try again.
An Option<T> in Rust should occupy the size of T plus the size of a discriminant. On a 64-bit machine for example an Option<i32> will take up 8 bytes. Four bytes for the i32 and four bytes (including alignment) for the discriminant. A 100% increase in space is clearly a performance hit.
If, however, T is a non-nullable type, the Rust compiler is smart enough to use this null value as a sentinel and you end up with an Option<T> that only takes up the size of T.
So, for example, both a &i32 and an Option<i32> will take 8 bytes, no difference, zero waste.
for example?
It might be more instructive to list some exceptions:
- As described elsewhere in this thread, Julia is able to optimize Array<Option<X>> internally into a bitfield and a tightly-packed array of X
- Rust can use knowledge of a type's valid values to optimize Option<T> into something the same size of T for common T (pointers, arrays, etc, also notably I think user-defined enums which aren't exhaustive of their value space) - but as far as I know it cannot do what Julia does, you need to reach for e.g. https://docs.rs/vec-option/latest/vec_option/
- This is somewhat the raison d'etre for Jai, if it ever gets released.
to make it obvious, post some code.
bool m_initialized ;
storage_type m_storage ;FWIW, we have had this discussion a few months ago on HN.
(The compiler is allowed to improve this, but it won't.)
But those languages are very good at pretending they mix the two concepts.