-
Notifications
You must be signed in to change notification settings - Fork 5
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
Use a bit set optimization for unit variant keys #36
Comments
This is a really interesting idea. Rather than optimistically implementing At least as a starting point, require that all variants are manually assigned an integer. And then within the BitKey derive macro, enforce that bit assignments must be contiguous. There can not be any skipped bits, but they don't have to start at the first bit. This makes the iterator easy. And check that there are no bit conflicts. |
Another thing: it is technically possible to support non-unit variant keys (as long as they don't have any dynamic inners) by match-mapping the variants to integers. #[derive(Clone, Copy, Key, BitKey)]
enum Key {
One,
Two(Option<()>),
Four(Option<Option<bool>>),
}
impl BitKey for Key {
fn contains(&self, key: Self) {
let mask = match key {
Key::One => 0b0000_0001,
Key::Two(Some(_)) => 0b0000_0010,
Key::Two(None) => 0b0000_0100,
Key::Four(Some(Some(true))) => 0b0000_1000,
Key::Four(Some(false))) => 0b0001_0000,
Key::Four(Some(None)) => 0b0010_0000,
Key::Four(None) => 0b0100_0000,
};
...
}
} Obviously this couldn't be as optimal as the unit variant only case, but it is possible. |
It's an interesting proposition, all though I'm not sure if it's possible in the generic sense: since we don't have access to type information we'd have to guess that the type identifier Or use an attribute It's an interesting idea though. But I'd be more than happy to only have simple unit variants work first. |
When following key:
Is stored in a Set it is currently backed by a structure like this since it's based on a map storing
()
values: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: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:Without that it might be difficult to ensure that certain operations are optimal, to the same degree as a manual bitset:
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.The text was updated successfully, but these errors were encountered: