Skip to content

Optimize the representation of NotNaN #114

Open

Description

@notgull

Here's a thought experiment which would almost certainly be a breaking change, but something worth looking into nonetheless.

Right now, the inner representation of a NotNan<T> is a T. However, we know one thing about the value: it will never (soundly) be a NaN. Using this information, we could optimize the inner representation of the type so that Option<NotNan<T>> is a no-op. This could be done by using wrapping addition and subtraction combined with NonZeroU32/NonZeroU64. What are your thoughts on this?

Activity

  1. mbrubeck commented on Oct 24, 2022

    @mbrubeck
    Collaborator

    rust-lang/rfcs#3334 would be the ideal way to allow this optimization, if it is eventually accepted and stabilized.

  2. soooch commented on Feb 15, 2023

    @soooch

    fyi rust-lang/rfcs#3334 was closed in favor of rust-lang/rust#103724 which in turn was closed in favor of rust-lang/rust#107606

  3. Artoria2e5 commented on Jun 29, 2025

    @Artoria2e5

    It's closed (June 2023), so back to wrapping add or xor we go. In the more naive implementation it's just a NonZeroU32/64 wrapped with an XOR on a number with all 1 in the exponent field and at least an 1 in the mantissa. This will allow one of the NaN values to have a representation of exactly 0, allowing Option to use it. That would break repr(transparent) though, so that's one major version bump.

    In the ideal world you would have the ability to break a float down into

    enum Float64Guts {
      Nan(Sign: u1, Signal: u1, Payload: NonZeroU51),
      NonNan<f64>
    }
    

    and some magical fairy allows you to pack some error types into that payload. But hey we can't even pack exactly one option there now that niche/whatever isn't going through...

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions