-
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
2229: Reduce the size of closures with capture_disjoint_fields
#86701
Conversation
I profile the change in closure size before and after the change on the rust compiler: Baseline: https://docs.google.com/spreadsheets/d/1U5vaXu490wn8Ae1LB1mSfoP_EZrGRHbUU6ADbeY8bn4/edit#gid=545238654 Some details about the sheets:
I had to output the data to stdout to get data from each dependency and crate that is compiled and ended up making a one off error while filtering out the boostrap output. I have another PR that allows profiling using a compiler flag: #86695 |
@@ -0,0 +1,31 @@ | |||
#![feature(capture_disjoint_fields)] |
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.
waiting on the editon PR to go in for this to work
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.
To change this to use edition*
Notes from 2229 sync: https://hackmd.io/hpjgfcwaSK20uFtZibwhIw |
☔ The latest upstream changes (presumably #86704) made this pull request unmergeable. Please resolve the merge conflicts. |
One key observation while going over the closure size profile of rustc was that we are disjointly capturing one or more fields starting at an immutable reference. Disjoint capture over immutable reference doesn't add too much value because the fields can either be borrowed immutably or copied. One possible edge case of the optimization is when a fields of a struct have a longer lifetime than the structure, therefore we can't completely get rid of all the accesses on top of sharef refs, only the rightmost one. Here is a possible example: ```rust struct MyStruct<'a> { a: &'static A, b: B, c: C<'a>, } fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static { let c = || drop(&*m.a.field_of_a); // Here we really do want to capture `*m.a` because that outlives `'static` // If we capture `m`, then the closure no longer outlives `'static' // it is constrained to `'a` } ```
@bors delegate+ r=me with comments added |
✌️ @arora-aman can now approve this pull request |
@bors r+ |
📌 Commit 38dcae2 has been approved by |
☀️ Test successful - checks-actions |
One key observation while going over the closure size profile of rustc
was that we are disjointly capturing one or more fields starting at an
immutable reference.
Disjoint capture over immutable reference doesn't add too much value
because the fields can either be borrowed immutably or copied.
One possible edge case of the optimization is when a fields of a struct
have a longer lifetime than the structure, therefore we can't completely
get rid of all the accesses on top of sharef refs, only the rightmost
one. Here is a possible example:
r? @nikomatsakis