Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization opportunity for optional enum values #12186

Open
ikskuh opened this issue Jul 21, 2022 · 3 comments
Open

Optimization opportunity for optional enum values #12186

ikskuh opened this issue Jul 21, 2022 · 3 comments
Milestone

Comments

@ikskuh
Copy link
Contributor

ikskuh commented Jul 21, 2022

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:

This idea originated from a discussion in the Zig discord.

@0x08088405
Copy link
Contributor

0x08088405 commented Jul 21, 2022

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.

@rohlem
Copy link
Contributor

rohlem commented Jul 21, 2022

seems related to #104

@orent
Copy link

orent commented Sep 4, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants