-
Notifications
You must be signed in to change notification settings - Fork 583
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
perf: improve deserialization of value encoding for struct/list #5897
Conversation
Codecov Report
@@ Coverage Diff @@
## main #5897 +/- ##
==========================================
+ Coverage 74.85% 74.92% +0.06%
==========================================
Files 922 923 +1
Lines 146824 146931 +107
==========================================
+ Hits 109911 110082 +171
+ Misses 36913 36849 -64
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
This is interesting. I find that the lower bound of the size hint in impl<I, R> Iterator for GenericShunt<'_, I, R>
where
I: Iterator<Item: Try<Residual = R>>,
{
type Item = <I::Item as Try>::Output;
fn next(&mut self) -> Option<Self::Item> {
self.try_for_each(ControlFlow::Break).break_value()
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.residual.is_some() {
(0, Some(0))
} else {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
} So when we're calling impl<T, I> SpecFromIterNested<T, I> for Vec<T>
where
I: Iterator<Item = T>,
{
default fn from_iter(mut iterator: I) -> Self {
// Unroll the first iteration, as the vector is going to be
// expanded on this iteration in every case when the iterable is not
// empty, but the loop in extend_desugared() is not going to see the
// vector being full in the few subsequent loop iterations.
// So we get better branch prediction.
let mut vector = match iterator.next() {
None => return Vec::new(),
Some(element) => {
let (lower, _) = iterator.size_hint();
let initial_capacity =
cmp::max(RawVec::<T>::MIN_NON_ZERO_CAP, lower.saturating_add(1));
let mut vector = Vec::with_capacity(initial_capacity);
unsafe {
// SAFETY: We requested capacity at least 1
ptr::write(vector.as_mut_ptr(), element);
vector.set_len(1);
}
vector
}
};
// must delegate to spec_extend() since extend() itself delegates
// to spec_from for empty Vecs
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
vector
}
} So almost all |
That's too bad, I have seen so many |
There is already an issue here rust-lang/rust#48994 |
I hereby agree to the terms of the Singularity Data, Inc. Contributor License Agreement.
What's changed and what's your intention?
The benchmark result is as follows, the deserialization time was reduced by about 40-50%
Checklist
- [ ] I have written necessary rustdoc comments- [ ] I have added necessary unit tests and integration tests./risedev check
(or alias,./risedev c
)Refer to a related PR or issue link (optional)
#5713