-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Preallocate the vector containing predicates in decode_predicates #55534
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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.