Skip to content

Space-optimize Option<T> for integral enum T #14540

Closed

Description

_Summary_
I propose a space optimization for variables of type Option<E> when E is a nullary, integral enum type.

_Motivation_
There's no need to waste memory for storing a separate tag in variables of type Option<E> if E is an integral enum type and the set of valid values of E does not cover all possible bit patterns. Any bit pattern (of the size of E) that doesn't represent a valid value of type E could be used by the compiler to represent the None value of type Option<E>.

_Details_
Given a nullary, integral enum type E, the compiler should check if some bit pattern exists which does not represent a valid value of type E (the only valid values are the ones determined by the nullary enum variants of E). If such "invalid" bit patterns are found, the compiler should use one of them to represent the None value of type Option<E> and omit storing the tag in variables of type Option<E>. If more than one such "invalid" bit pattern exists, there should be a language defined method to deterministically determine which one of those bit patterns is used to represent the None value. I think the bit pattern of None should be language defined rather than implementation defined in order to make Option<E> values serialized to disk more stable between different compilers / compiler versions.

In determining whether a certain value of such space optimized type Option<E> is None or not, the algorithm should simply check whether or not the binary representation of said value is equal to the binary representation of the language defined "invalid" value.

Activity

  1. erickt commented on Jun 3, 2014

    @erickt
    Contributor

    I whipped up a dummy example to see how this would optimize Option<Result<T, E>> types, and it has a pretty nice 8% speedup: https://gist.github.com/erickt/8a6be5c8a2542eaf0c45. This would be especially helpful for my libserialize rewrite RFC.

  2. pczarn commented on Jun 5, 2014

    @pczarn
    Contributor

    Don't you think it could be done transitively for all tagged unions and integral enum types?

    I have three optimizations on my mind:

    • use free patterns for zero-length variant representations in non-integral enums, including checks for nullable pointers and all of the above
    • allow #[repr(int type)] on non-integral enums
    • use #[packed] on enums to force all possible optimizations

    I think the bit pattern of a variant should should be as close to 0 as possible in the order of declaration, just like in integral enums. It could stay undefined or become implementation defined

  3. huonw commented on Jun 5, 2014

    @huonw
    Contributor

    use #[packed] on enums to force all possible optimizations

    Why wouldn't this be the default? (That is, why would all optimisations be applied by default.)

  4. pczarn commented on Jun 13, 2014

    @pczarn
    Contributor

    @huonw, because it's a space-time tradeoff. Ideally, all possible values of an ADT could be represented within a minimal number of bits. However, values can be moved out of enums, so they should exist somewhere with proper alignment. Matching complex packed enums could still get expensive without simple discriminants:

    enum Value {
      A = 20,
      B = 21,
    }
    
    // Option<Result<Value, IoErrorKind>>
    match maybe_result {
      // matches on {22, _}
      None => a,
      // matches on {18, 0}
      Some(Err(ShortWrite(0))) => b,
      // matches on {x, _} if 20 <= x && x < 22
      Some(Ok(_)) => c,
    }
  5. pczarn commented on Oct 1, 2014

    @pczarn
    Contributor

    Of course, sorry, I was referring to something else.

  6. steveklabnik commented on May 24, 2016

    @steveklabnik
    Contributor

    Triage: no changes I'm aware of.

  7. Mark-Simulacrum commented on May 19, 2017

    @Mark-Simulacrum
    Member

    I'm going to close this in favor of rust-lang/rfcs#1230 since there's a lot of potential layout optimizations involving enums but this one specific issue isn't key enough that it should be tracked separately.

  8. added 3 commits that reference this issue on Oct 14, 2017
    3bd11e7
  9. 1 remaining item

  10. added a commit that references this issue on Jun 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions