Skip to content

fix perf regression from abby canonical form - #162531

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
khyperia:abby-perf
Sep 10, 2026
Merged

fix perf regression from abby canonical form#162531
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
khyperia:abby-perf

Conversation

@khyperia

@khyperia khyperia commented Sep 9, 2026

Copy link
Copy Markdown
Member

View all comments

#161306 regressed performance on stable

I believe all the perf impact is due to this

solver_region_constraint_storage: SolverRegionConstraintStorage::new(),

before, SolverRegionConstraintStorage was a dummy simple thing, no allocations.

now, it's a RegionConstraint { and: Box([]), or: Box([Box([])]) }

the majority of the perf impact (70%ish I think) is because the compiler is not sufficiently smart to optimize And::new([]) into And(Box::new([])) (the former does a bunch of IndexSet allocations and stuff, the latter is a no-op, just a nullptr plus zero length metadata)

the the rest of the perf impact (30%ish) is due to the or case allocating the Box([Box([])]), it's not just a nullptr+zero

options to fix:

  • option A: just fix the And::new([]) being terrible
  • option B: option A, and also, SolverRegionConstraintStorage stores an Option that is lazily init on first access, to prevent the perf hit from the or case
  • option C: option A, and also, use some kind of SmallVec something or other to make the or case be zero-alloc. I have not profiled this due to it being an invasive change and effort, this might not actually fix the perf.

This PR is out option A to see if it actually works with the full perf machinery with PGO and whatnot instead of just on my machine (I am very inexperienced with perf testing!). It might be the case that full PGO blah blah is actually sufficiently smart to optimize And::new([]), and the actual perf diff is due to the or case (which I'm calling the 30%ish impact, might be actually 100%), in which case this PR should produce a no-op perf diff.

r? @BoxyUwU

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 9, 2026
@rust-log-analyzer

This comment has been minimized.

@khyperia

khyperia commented Sep 9, 2026

Copy link
Copy Markdown
Member Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 9, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 9, 2026
fix perf regression from abby canonical form
@rust-bors

rust-bors Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 6045edf (6045edfc980d86d93057e102a0447621562f9c8b)
Base parent: 55c4dfe (55c4dfed758e741620e3320ed472ff5c4140856a)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (6045edf): comparison URL.

Overall result: ✅ improvements - no action needed

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.2% [-0.8%, -0.1%] 21
Improvements ✅
(secondary)
-0.2% [-0.3%, -0.1%] 11
All ❌✅ (primary) -0.2% [-0.8%, -0.1%] 21

Max RSS (memory usage)

Results (primary 0.0%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.1% [0.7%, 5.0%] 3
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.1% [-5.2%, -0.5%] 3
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.0% [-5.2%, 5.0%] 6

Cycles

Results (primary -0.0%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.7% [0.5%, 1.0%] 9
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.1% [-2.3%, -0.7%] 6
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.0% [-2.3%, 1.0%] 15

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 480.775s -> 481.555s (0.16%)
Artifact size: 403.36 MiB -> 403.42 MiB (0.02%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 9, 2026
@khyperia

khyperia commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

looks like when I said

  • 70%ish of the perf impact is because of an insufficiently smart compiler to optimize And::new([]) into And(Box::new([]))
  • 30%ish of the perf impact is because of allocating in the default path for an empty true region constraint due to Or

when under PGO and whatnot instead of my local machine, seeeems the first point is more like 15% rather than 70%. (this PR is fixing just the first point, and seems to come back as recovering 15% of the original regression)

I don't know how to read the online web report, but running these locally:

cargo build --release -p collector && ./target/release/collector profile_local cachegrind +4fcf39725a9c99bd495d8c73af83628a256ff9a9 --rustc2 +d8df82673d5911b6112a85bf91d9adefb2c66a1a --exact-match libc-0.2.172 --profiles Check --scenarios Full # original regression
cargo build --release -p collector && ./target/release/collector profile_local cachegrind +55c4dfed758e741620e3320ed472ff5c4140856a --rustc2 +6045edfc980d86d93057e102a0447621562f9c8b --exact-match libc-0.2.172 --profiles Check --scenarios Full # this PR

shows the first one as +8,686,194 PROGRAM TOTALS, this PR as -1,324,876 PROGRAM TOTALS

still, this PR came back fully green, so I'm down to merge this as-is, I'll undraft this. I'll try to poke around and investigate further to remove the alloc on the Or path, if this PR isn't r+ by then I'll probably schlorp it into this PR, otherwise I'll just make a new PR.

@rustbot

rustbot commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

BoxyUwU is currently at their maximum review capacity.
They may take a while to respond.

@khyperia
khyperia marked this pull request as ready for review September 10, 2026 06:57
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 10, 2026
@rustbot

rustbot commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

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.

@khyperia

Copy link
Copy Markdown
Member Author

pushed option B in the PR description, will do a perf run on that too. since yeah, basically what panstromek said in zulip:

I feel like in your situation (working on important but unstable feature) you kinda want to quickly put the perf aside and focus on the important bits first.

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 10, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 10, 2026
fix perf regression from abby canonical form
@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: d851dfd (d851dfd72cbfb660ee4f04b3de37881d03833cae)
Base parent: c4c4a57 (c4c4a576936e9e67717d0deb8e74e02dd5dd10de)

@rust-timer

This comment has been minimized.

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors retry

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 10, 2026
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

A job failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

A job failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors p=10

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 10, 2026
fix perf regression from abby canonical form



#161306 regressed performance on stable

I believe all the perf impact is due to this

https://github.com/rust-lang/rust/blob/d8df82673d5911b6112a85bf91d9adefb2c66a1a/compiler/rustc_infer/src/infer/mod.rs#L186

before, `SolverRegionConstraintStorage` was a dummy simple thing, no allocations.

now, it's a `RegionConstraint { and: Box([]), or: Box([Box([])]) }`

the majority of the perf impact (70%ish I think) is because the compiler is not sufficiently smart to optimize `And::new([])` into `And(Box::new([]))` (the former does a bunch of `IndexSet` allocations and stuff, the latter is a no-op, just a nullptr plus zero length metadata)

the the rest of the perf impact (30%ish) is due to the `or` case allocating the `Box([Box([])])`, it's not just a nullptr+zero

options to fix:

- option A: just fix the `And::new([])` being terrible
- option B: option A, *and also*, `SolverRegionConstraintStorage` stores an `Option` that is lazily init on first access, to prevent the perf hit from the `or` case
- option C: option A, *and also*, use some kind of `SmallVec` something or other to make the `or` case be zero-alloc. I have not profiled this due to it being an invasive change and effort, this might not actually fix the perf.

This PR is out option A to see if it actually works with the full perf machinery with PGO and whatnot instead of just on my machine (I am very inexperienced with perf testing!). It might be the case that full PGO blah blah *is* actually sufficiently smart to optimize `And::new([])`, and the actual perf diff is due to the `or` case (which I'm calling the 30%ish impact, might be actually 100%), in which case this PR should produce a no-op perf diff.

r? @BoxyUwU
@rust-bors rust-bors Bot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Sep 10, 2026
@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

💔 Test for 5261ebd failed: CI. Failed job:

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors treeclosed=10 Runner problem git not found on EC2 runners

@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Tree closed for PRs with priority less than 10.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

A job failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors retry

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 10, 2026
@rust-bors

This comment has been minimized.

@JonathanBrouwer

Copy link
Copy Markdown
Member

@bors treeopen
sorry for all the tree commands on this pr :3

@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Tree is now open for merging.

@rust-bors rust-bors Bot added merged-by-bors This PR was explicitly merged by bors. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Sep 10, 2026
@rust-bors

rust-bors Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

☀️ Test successful - CI
Approved by: BoxyUwU
Duration: 3h 8m 58s
Pushing 67eda61 to main...

@rust-bors
rust-bors Bot merged commit 67eda61 into rust-lang:main Sep 10, 2026
15 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Sep 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor
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 018018e (parent) -> 67eda61 (this PR)

Test differences

Show 10 test diffs

10 doctest diffs were found. These are ignored, as they are noisy.

Test dashboard

Run

cargo run --manifest-path src/ci/citool/Cargo.toml -- \
    test-dashboard 67eda617e6a8f8ecec01e1ba7fafe2072a64adcc --output-dir test-dashboard

And then open test-dashboard/index.html in your browser to see an overview of all executed tests.

Job duration changes

  1. dist-x86_64-solaris: 1h 15m -> 1h 47m (+43.6%)
  2. dist-i686-mingw: 55m 31s -> 34m 20s (-38.2%)
  3. test-x86_64-gnu-next-trait-solver-polonius: 44m 55s -> 1h 1m (+36.5%)
  4. test-x86_64-gnu-miri: 1h 3m -> 1h 24m (+33.0%)
  5. test-pr-check-1: 28m 44s -> 38m 9s (+32.8%)
  6. dist-apple-various: 1h 53m -> 2h 25m (+27.8%)
  7. dist-sparcv9-solaris: 1h 14m -> 1h 34m (+27.4%)
  8. dist-s390x-linux: 1h 31m -> 1h 6m (-27.3%)
  9. dist-powerpc64-linux-musl: 1h 15m -> 1h 35m (+27.0%)
  10. dist-arm-linux-gnueabi: 1h 33m -> 1h 8m (-26.0%)
How to interpret the job duration changes?

Job durations can vary a lot, based on the actual runner instance
that executed the job, system noise, invalidated caches, etc. The table above is provided
mostly for t-infra members, for simpler debugging of potential CI slow-downs.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (67eda61): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.1% [0.1%, 0.1%] 1
Improvements ✅
(primary)
-0.3% [-0.6%, -0.1%] 75
Improvements ✅
(secondary)
-0.3% [-0.8%, -0.0%] 57
All ❌✅ (primary) -0.3% [-0.6%, -0.1%] 75

Max RSS (memory usage)

Results (primary 0.5%, secondary -2.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.9% [0.4%, 2.2%] 4
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.8% [-0.8%, -0.8%] 1
Improvements ✅
(secondary)
-2.7% [-2.7%, -2.7%] 1
All ❌✅ (primary) 0.5% [-0.8%, 2.2%] 5

Cycles

Results (primary -0.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.9% [0.5%, 1.5%] 3
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.7% [-1.0%, -0.4%] 7
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.2% [-1.0%, 1.5%] 10

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 479.823s -> 476.479s (-0.70%)
Artifact size: 403.70 MiB -> 403.80 MiB (0.02%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants