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

optional type optimization #104

Open
andrewrk opened this issue Feb 2, 2016 · 4 comments
Open

optional type optimization #104

andrewrk opened this issue Feb 2, 2016 · 4 comments
Assignees
Labels
accepted This proposal is planned. optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Feb 2, 2016

Track which values are used when data sizes are bigger than necessary and use those states for maybe types. For example, ?bool could use value 2 of the bool as the null value, and ??bool can use value 3 for the null value, and so on.

If we have spaces in structs for alignment purposes, that space could be used for the null value, or if any of the fields have null space available, such as a struct with a bool field in it somewhere.

@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. lowpriority optimization labels Feb 2, 2016
@andrewrk
Copy link
Member Author

andrewrk commented Feb 3, 2016

Also, if you do ?void or equivalent, then you have effectively constructed a boolean, and this can codegen to the same as what a boolean codegens to.

andrewrk added a commit that referenced this issue Mar 10, 2017
@andrewrk andrewrk modified the milestone: 0.3.0 May 20, 2017
@andrewrk andrewrk modified the milestones: 0.3.0, 0.4.0 Feb 28, 2018
@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Sep 28, 2018
@andrewrk andrewrk added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. and removed enhancement Solving this issue will likely involve adding new logic or components to the codebase. labels Apr 11, 2019
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Apr 11, 2019
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Oct 17, 2019
@andrewrk andrewrk changed the title maybe type optimization optional type optimization Nov 27, 2019
@andrewrk andrewrk added the frontend Tokenization, parsing, AstGen, Sema, and Liveness. label Nov 27, 2019
@iansimonson
Copy link
Contributor

Based on @LemonBoy 's suggestion copying the relevant parts of #5162 to here. Though it seems you called this proposal out already above.

Edited the parts below to be more concise.

Optional structs can have some drastic effects on the sizes. Specifically if the alignment of a field is large (e.g. larger than the normal sizes of each field) an optional struct can easily double in size e.g.:

const S = struct {
    a: u8 align(64),
};

test "Alignment" {
    std.debug.assert(@sizeOf(S) == 64);
    std.debug.assert(@sizeOf(?S) == 128);
    std.debug.assert(@sizeOf(?S) == @sizeOf(S)   @alignOf(S));
}

Since Zig doesn't have a stable ABI for its own structs it should be possible to optimize an optional type's layout and size to use the generated padding to host the extra optional field.

This would effectively bring the @sizeof(?S) in the example down to 64 and shouldn't have any issues with e.g. var set_of_s: [100]S = undefined; as the type S would stay properly aligned.

Of course it won't always be possible to do this optimization, in which case the optional type would have to add the additional field as normal.

@iansimonson
Copy link
Contributor

Also to highlight since it's relevant to this issue - @SpexGuy 's suggestion of Explicit Sentinel Optionals from: #3806 (comment)

@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 9, 2020
@andrewrk andrewrk added accepted This proposal is planned. and removed frontend Tokenization, parsing, AstGen, Sema, and Liveness. labels Apr 21, 2021
@andrewrk
Copy link
Member Author

This is accepted which means that:

  • ?T is a non-memory-defined layout, with the exception of pointers, which have well-defined memory layout
  • ?T where T has no well-defined memory layout, zig is allowed to choose any representation for the ?T
  • &foo.? is legal; you can take the pointer of T in an ?T. The T has to be addressable.
  • You cannot take the pointer of the optional bit in a ?T. The optional bit is not addressable.

@SpexGuy SpexGuy self-assigned this Apr 22, 2021
@andrewrk andrewrk removed this from the 0.8.0 milestone May 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. optimization proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

3 participants