Skip to content

Use a bit set optimization for unit variant keys #36

@udoprog

Description

@udoprog

When following key:

#[derive(Key)]
enum MyKey {
    First,
    Second,
    Third,
}

Is stored in a Set it is currently backed by a structure like this since it's based on a map storing () values:

struct Storage {
    data: [Option<()>; 3],
}

Which occupies 3 bytes. This could instead be optimized to make use of a bit set (like I do in bittle) who's size depends on the number of variants:

struct SetStorage {
    // can represent 8 distinct values.
    data: u8,
}

Performance Musings

Whether this would be "as good" as a manually implemented bitset is hard to say. It might require additional specialization such as ensuring that MyKey is #[repr(<integer>)] and that each variant specifies a distinct value, such as:

#[derive(Key)]
#[repr(u8)]
#[key(bitset = "u8")]
enum MyKey {
    First = 0b1000,
    Second = 0b0100,
    Third = 0b0010,
}

Without that it might be difficult to ensure that certain operations are optimal, to the same degree as a manual bitset:

let set = 0b1001;

// contains
if set & MyKey::First as u8 != 0 {
    // and so forth.
}

Iteration might be the hardest one to perform with good performance, but in all fairness that is also something which is difficult with a manual bitset. Ensuring some representation and that each variant is reliably specified might mean that it's possible to coerce values into MyKey (unsafely) which wouldn't be easy to do manually.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions