-
Notifications
You must be signed in to change notification settings - Fork 159
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
Parameterize the index type of maps and sets #147
Conversation
b61fdd4
to
33d9b31
Compare
Nice idea and pretty smooth implementation. With the into/from usize conversion, we insert a lot more panic sites in the code. And I'd like to ensure we can't panic in places that leave the map inconsistent. (Is this a too onerous goal?) The first usize conversion in Then we document that insert panics if the index type's limits are exceeded etc. (And .extend() and .collect() et.c. 🙁 I'm just sad that it gets ugly in the details.) |
@bluss it's not clear to me that a smaller index type needs special treatment – after all, the current logic also panics if an allocation can't be met (for whatever reason, possibly capacity > usize). |
@malthe That's too hand-wavy, the exact line and place where we can panic matters for which inconsistencies can show up in the data structure. |
@bluss but if we panic, what's left of the program? Is it not just going to halt? Another issue I found was that it feels inconsistent that |
Panic is recoverable, so that's why it matters. |
@cuviper I have begun some rebasing against the current master on this one, but let me know if you already have something cooking. |
Len should probably continue to return usize, just to note - without looking deeper. |
@malthe Sorry, I don't know how far you got, but I just pushed a rebase myself. I was responsible for a lot of the conflicting changes anyway, so I had a good idea how to solve things. I have mixed feelings whether the length and capacity should be |
@cuviper yeah I think it has to be |
The index type is a new generic parameter defaulting to `usize`: pub struct IndexSet<T, S = RandomState, Idx = usize> pub struct IndexMap<K, V, S = RandomState, Idx = usize> In `no_std` builds, `S` has no default, but still `Idx = usize`. This may be used to optimized the storage size in the raw table, for example using a `u32` index if you know that `u32::MAX` capacity is sufficient for you. It may also be useful to define a newtype index custom to a particular domain, which only needs to implement the new `Indexable` trait to be useful here.
Looking for real-world results on indexmap-rs/indexmap#147.
To get some real data, I tried to use this branch in rust-lang/rust#96751 and its perf infrastructure. For instructions, there were a few small wins, but nothing better than 1% improvement, and one case regressed 1.68%. Maybe that's a good thing that it was mostly neutral, since this has added It's possible that I just didn't make good use of it, but those were all the places I could find that clearly dealt with smaller indexes. Maybe there are more significant maps that would be happy limited to Overall, I'm not inclined to merge this if there's no clear winner, as the new parameter is pretty invasive. |
The index type is a new generic parameter defaulting to
usize
:In
no_std
builds,S
has no default, but stillIdx = usize
.This may be used to optimized the storage size in the raw table, for
example using a
u32
index if you know thatu32::MAX
capacity issufficient for you. It may also be useful to define a newtype index
custom to a particular domain, which only needs to implement the new
Indexable
trait to be useful here.