Optimize handling of solver errors - #160160
Conversation
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Check for the empty case in `collect_remaining_errors()`
|
|
||
| fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> { | ||
| #[allow(clippy::iter_skip_zero)] | ||
| if self.obligations.pending.is_empty() && self.obligations.overflowed.is_empty() { | ||
| // In 99.983% this is true, so this helps perf. | ||
| return Vec::new(); | ||
| } | ||
|
|
||
| self.obligations |
There was a problem hiding this comment.
One other thing I'd try later too is that sometimes it helps is to put #[inline] on the function and wrap the rest of the code after the fast path in outline(move || { ... })).
There was a problem hiding this comment.
True, I also wanted to check if making this ThinVec will help since it will return in a register. It may cancel with outlining though.
|
@bors cancel |
|
❗ There is currently no auto build in progress on this PR. Hint: There is a pending try build on this PR. Maybe you meant to cancel it? You can do that using |
|
@bors try cancel |
|
Try build cancelled. Cancelled workflows: |
1223716 to
fbe4c63
Compare
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Check for the empty case in `collect_remaining_errors()`
|
I think it's worth checking this in std's TrustedLen specializations. The code is querying the size-hint anyway, it might as well bail early rather than invoking the |
|
It might be interesting, but std's specialization applies to much more diverse range of behaviors. There we can't know if "empty most of the times" is the common case. |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (f5bcd01): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -3.6%, secondary 0.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 0.4%, secondary 0.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 489.658s -> 489.161s (-0.10%) |
|
Okay, so not only this does not regress #160073 this also has a non-negligible improvement. Seems worth to merge, but I'll try to see if I can use |
|
Yea, the |
|
|
|
To the reviewer: The commits are fully separate. I can create separate PRs, but the first commit is very small so I don't think it's needed. |
collect_remaining_errors()6f6965c to
838f636
Compare
This comment has been minimized.
This comment has been minimized.
838f636 to
a41a292
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a41a292 to
4fcd53a
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
As it's very common.
This has multiple advantages: - Performance. The new type is 1/3 the size of `Vec` (being equivalent in layout to `Option<ThinVec>`) and can be kept in a register. - Type safety. We mark the type `#[must_use]`, and thinks requiring errors take `ThinVec`, which requires unwrapping the type and verifying there is indeed an error. We still provide conversions to slices, `ThinVec`, and iteration, because some code needs this and I saw no benefit in changing it, but we deliberately do not provide `Deref<Target = [E]>` or things like that.
4fcd53a to
5491ec8
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing 88f7399 (parent) -> ae45457 (this PR) Test differencesShow 44 test diffs44 doctest diffs were found. These are ignored, as they are noisy. Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard ae45457594a670c59cd4d5591eaa243d9a3d44d5 --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
View all comments
Check for the empty case in
collect_remaining_errors().Instead of representing trait errors as
Vec<Error>, use a special typeThis has multiple advantages:
Vec(being equivalent in layout toOption<ThinVec>) and can be kept in a register.#[must_use], and thinks requiring errors takeThinVec, which requires unwrapping the type and verifying there is indeed an error. We still provide conversions to slices,ThinVec, and iteration, because some code needs this and I saw no benefit in changing it, but we deliberately do not provideDeref<Target = [E]>or things like that.