-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Preallocate the vector containing predicates in decode_predicates #55534
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
f942665
to
2fe010b
Compare
Does this actually change anything? I thought using the range with |
@eddyb the original version collects into a Result, so the final capacity is unknown (because it can result in an error). This change expects an Ok Result and allocates for the full vector. |
The difference in performance can be quite significant: example. |
@ljedrz I frankly would've expected the full capacity to be allocated even for @gankro @alexcrichton @bluss What's happening here, why are things the way they are? |
Threre is a related issue (#48994), but the attempts to crack it have been unsuccessful so far. |
I think #52910 shouldn't have been closed, just redone using specialization. |
@eddyb I'm not too savvy with specializations, but I took a stab at it; would it look something like this?
|
@ljedrz Maybe, but I think you need the more general implementation, and that would have I think you need to talk to someone from @rust-lang/libs - which is why discussion should've continued on #52910. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts?
}?; | ||
Ok((predicate, Decodable::decode(decoder)?)) | ||
}) | ||
.collect::<Result<Vec<_>, _>>()?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm mistaken, the iterator will already pre-allocate a vector of the right size here, so this doesn't really buy us anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lower bound of size_hint
for the implementation of FromIterator
for Result
is equal to zero and the implementation of from_iter
for Vec
uses it to calculate the capacity. I don't think this is a case of TrustedLen
(due to non-conforming size_hint
), otherwise this PR (where the number of elements iterated over is known) wouldn't benefit from such a change either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also see I missed a lot of discussion on this topic already 😊
Do we care enough to measure this? I'm sort of inclined to just r+, but I wonder what @eddyb thinks? Do we have enough information to compute the "max" length? Maybe we could have a variant of |
I think @eddyb's idea regarding specialization is a good general approach to solving this (optimizing for the probably most common all- |
@nikomatsakis I think we should try to figure out how to use specialization to pass the right length from "collect into a |
In that case, should we close this PR? Land it in the meantime? Do we have any perf measurements? |
@nikomatsakis Close this, reopen #52910 (which had already been FCP-approved before considered to break a "law" of |
decode_predicates
is marked as#[inline]
, so this extra bit of performance could be worthwhile. As an added bonus this makes the returned object more readable.