zig icon indicating copy to clipboard operation
zig copied to clipboard

Optimization opportunity for optional enum values

Open ikskuh opened this issue 2 years ago • 2 comments

A lot of exhaustive enums don't use up the full number of options for their storage class, thus they have leftover bits or values.

We can take advantage of these bits to reduce the memory footprint of optional values to these enums by using one of the following storage strategies:

  1. Adding a hidden enum variant is_null that will be encoded as the last possible value in the integer space
  2. Storing a additional bit in the MSB position for a is_null value.

Both variants work when we define the padding bits in a non-byte integer as 0 which then, when accessing the optional payload would overwrite the is_null marker with "not set", which is always ok as we're not allowed to point to the payload of a optional type anyways if that type is null.

This optimization can be implemented transparent to the user and might not be required to be put into the language spec itself, but it would required a change in current language semantics.

Related proposals/issues:

  • #3806
  • #11263
  • #11761
  • #104

This idea originated from a discussion in the Zig discord.

ikskuh avatar Jul 21 '22 08:07 ikskuh

I think this a lot more broad than just enums as well, for example std.fmt.parseInt at the moment takes a radix argument that is either actually a real radix, or 0 is specially understood to let the function figure it out, whereas with something like #3806 this could just be an optional integer where x >= 1, with the compiler using zero as null, or for an example in production, rustc represents ?fd the same as fd since -1 is not a valid POSIX file descriptor so it can be utilised to represent null. Of course, there is the counter argument that instead of ?enum { a, b } you could simply write enum { a, b, none }, and I believe this is fine, but at the same time it also feels like a substitute for a concept we already have as a language feature. Additionally this optimisation could potentially make it harder to predict what the language will compile to, which some said does not make sense for a language as "bare-metal" as Zig, but I think it can coexist with the rest of the language, things like struct already have some magic happening with the memory representation, in this case it'd just be taking advantage of invalid states of the backing integer where possible.

0x08088405 avatar Jul 21 '22 09:07 0x08088405

seems related to #104

rohlem avatar Jul 21 '22 10:07 rohlem

How about @sizeOf(?u31) == @sizeOf(u32), etc?

orent avatar Sep 04 '22 13:09 orent