-
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
Make fold
standalone.
#72139
Make fold
standalone.
#72139
Conversation
Lots of iterator functions (e.g. If necessary, I could also add More generally,
It would be nice to make those smaller, but I'm struggling to see how to do it while still using cc @bluss |
@bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit 4f8acfc491360a39675b1beadcfa977f5b780b9d with merge 84327c568fbc9f25d682e9c2f0a3b8a0971d1c11... |
do not know if it is possible to do this change as it is documented to use try_fold |
@andjo403 it says "Most of the other (forward) methods have default implementations in terms of this one". That's not actually saying that any particular method indeed uses But if we go with this PR, a similar remark should likely be added to |
☀️ Try build successful - checks-actions, checks-azure |
Queued 84327c568fbc9f25d682e9c2f0a3b8a0971d1c11 with parent 09c817e, future comparison URL. |
The vision is that "Fortunately" To me seems like it would be acceptable to break the link between As a practical note, it is much easier for users to implement The methods Could there be some wild specialization marker that we could use on collection iterators in general to opt them out of using fn any(&mut self, f: impl FnMut(Self::Item) -> bool) -> bool {
IteratorSpecializations::any(self, f)
}
/* Default IteratorSpecializations::any uses try_fold */
/* libcore/alloc iterators marked as non-segmented use simple loop? */ (I don't know how to do this specialization without the unstable specialization marker traits, but we can certainly demonstrate here the difference in IR generated for the slice iterator in the two implementations - playground link) Reading the debug IR isn't so fun. No function is really innocent. Even raw pointer methods like |
I agree, I think it's OK to make this change specifically because Please give the same treatment to
We should audit those that currently have only
|
Finished benchmarking try commit 84327c568fbc9f25d682e9c2f0a3b8a0971d1c11, comparison URL. |
Perf looks like a solid win, except for |
In case it's useful, here is the full list of libstd iterators that implement An alternative option to this PR is to go in the other direction: remove all the
These are both interesting ideas. I will investigate them. Thanks! |
I think that would be actively harmful for adapters, since users can't implement |
I just analyzed
I also did some rough profiling of the rustc-perf benchmarks. The following shows the number of lines of LLVM IR associated with some of the methods, which gives an of their relative importances in relation to compile times.
|
It can be fraught to change which method is called in default implementation. Not that there is any problem in the current PR with that, but if we begin talking about switching around default implementations, it's a factor to think about. For example: If we would change |
I've done this in #72166, it's simple and gets a lot of the potential benefit. I will return to |
4f8acfc
to
0e4005d
Compare
I have updated the code. I've given |
I did some local measurements and couldn't replicate the ripgrep regression. Maybe it was just a one-off. If this gets r+ I will do another perf run. |
have you tested the perf together with #72166 is there any changes with this if that PR is merged? |
#72166 is mostly orthogonal to this. |
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.
Looks good, but there are a few that also need rfold
now that we've changed that. I noted those where you added fold
, and Skip
is one more.
`fold` is currently implemented via `try_fold`, but implementing it directly results in slightly less LLVM IR being generated, speeding up compilation of some benchmarks. (And likewise for `rfold`.) The commit adds `fold` implementations to all the iterators that lack one but do have a `try_fold` implementation. Most of these just call the `try_fold` implementation directly.
Many default iterator methods use `try_fold` or `fold`, and these ones can too.
0e4005d
to
b18651d
Compare
@cuviper: I have added the requested |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
b18651d
to
959bd48
Compare
@bors r+ |
📌 Commit 959bd48 has been approved by |
⌛ Testing commit 959bd48 with merge 1a814c344dd1588457199109c0722ff66765a295... |
💔 Test failed - checks-azure |
msys2 failure |
Rollup of 6 pull requests Successful merges: - rust-lang#71863 (Suggest fixes and add error recovery for `use foo::self`) - rust-lang#72139 (Make `fold` standalone.) - rust-lang#72275 (Continue lowering for unsupported async generator instead of returning an error.) - rust-lang#72361 (split_inclusive: add tracking issue number (72360)) - rust-lang#72364 (Remove unused dependencies) - rust-lang#72366 (Adjust the zero check in `RawVec::grow`.) Failed merges: r? @ghost
@bors rollup=never Because this affects performance. |
How did this land when some of the tests failed? |
It landed as part of a rollup that was created before you did rollup=never: #72378. All tests passed there. |
fold
is currently implemented viatry_fold
, but implementing itdirectly results in slightly less LLVM IR being generated, speeding up
compilation of some benchmarks.
r? @cuviper