-
-
Notifications
You must be signed in to change notification settings - Fork 456
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
Niche Optimization for Option<ReferenceId>
and IndexVec<ReferenceId, T>
#3318
Comments
This comment was marked as outdated.
This comment was marked as outdated.
There's also a much more complicated, but more performant solution. As far as I'm aware, the We could capitalize on this invariant to remove bounds checks. Something like: pub struct ReferenceVec(Vec<Whatever>);
pub struct ReferenceId(u32);
impl ReferenceId {
const EMPTY: Self = ReferenceId(0);
}
impl ReferenceVec {
pub fn new() -> Self {
// Initialize vec with a dummy at index 0
let mut inner = Vec::new();
inner.push(Whatever::default());
Self(inner)
}
pub fn push(&mut self, value: Whatever) -> ReferenceId {
let index = ReferenceId(self.0.len());
self.0.push(value);
index
}
// Returns `&Whatever` not `Option<&Whatever>`
// because `ReferenceId` is always a valid index
pub fn get(&self, index: ReferenceId) -> &Whatever {
// `index` must be in bounds, so skip bounds check
unsafe { self.0.get(index.0).unwrap_unchecked() }
}
// NB: No `pop` method
} i.e. The only way to get a Actual implementation would need to be more complex than the above. Would need some mechanism to prevent you using a NB: Unclear how much of a gain this would be, and whether worth the complexity. In my opinion, we should do the main change (shrink |
It seems like you're proposing a new crate for this use case, instead of reusing the crates I found from the community. Edit: the issue description is changed from |
define_index_type! { pub struct ReferenceId = NonMaxU32; }
Option<ReferenceId>
and IndexVec<ReferenceId, T>
I hope not! I thought the reason we swapped The append-only-with-no-bounds-checks |
Naive question: could you not subtract the index by 1 each time you want to access the element in the array? |
Yes we could, and for some use cases that would be a good solution. But personally I don't think it's ideal for ours, because:
Therefore, on balance, I think a dummy entry will be more performant for our use case. Does that make sense? |
I had some limited success with non-zero index here #3104, The Issue is that the performance gain I saw wasn't high enough for me to consider taking the risk of destabilizing index_vec with this major change. But as our The hard part is having to support all vector operations and its iterators, There are a lot of safety concerns to think about before switching to non zero indecis. And some operations are slow because of safety checks, We can switch to unsafe methods in our vector so we can gain more whenever it is safe to skip the checks. |
we have these index types
oxc/crates/oxc_syntax/src/reference.rs
Lines 6 to 8 in 712ee0d
oxc/crates/oxc_syntax/src/symbol.rs
Lines 7 to 9 in 712ee0d
where
oxc/crates/oxc_ast/src/ast/js.rs
Line 451 in 712ee0d
oxc/crates/oxc_semantic/src/reference.rs
Line 22 in 712ee0d
can be trimmed by niche optimization.
But,
is not supported by the macro
define_index_type
but the good news is that we forked it and lives in https://github.com/oxc-project/oxc/tree/main/crates/oxc_index
The task of this issue is to make it work, if possible.
The text was updated successfully, but these errors were encountered: