Skip to content
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

Avoid useless Vec clones in pending_obligations(). #51412

Merged
merged 1 commit into from
Jun 9, 2018

Conversation

nnethercote
Copy link
Contributor

The only instance of ObligationForest in use has an obligation type of
PendingPredicateObligation, which contains a PredicateObligation and a
Vec<Ty>.

FulfillmentContext::pending_obligations() calls
ObligationForest::pending_obligations(), which clones all the
PendingPredicateObligations. But the Vec<Ty> field of those cloned
obligations is never touched.

This patch changes ObligationForest::pending_obligations() to
map_pending_obligations -- which gives callers control about which part
of the obligation to clone -- and takes advantage of the change to avoid
cloning the Vec<Ty>. The change speeds up runs of a few rustc-perf
benchmarks, the best by 1%.

@rust-highfive
Copy link
Collaborator

r? @estebank

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 7, 2018
@alex
Copy link
Member

alex commented Jun 7, 2018

(whoops, didn't mean to submit that. sorry for the noise!)

pub fn pending_obligations(&self) -> Vec<O>
where O: Clone
pub fn map_pending_obligations<P, F>(&self, f: F) -> Vec<P>
where O: Clone,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That Clone bound isn't necessary anymore

The only instance of `ObligationForest` in use has an obligation type of
`PendingPredicateObligation`, which contains a `PredicateObligation` and a
`Vec<Ty>`.

`FulfillmentContext::pending_obligations()` calls
`ObligationForest::pending_obligations()`, which clones all the
`PendingPredicateObligation`s. But the `Vec<Ty>` field of those cloned
obligations is never touched.

This patch changes `ObligationForest::pending_obligations()` to
`map_pending_obligations` -- which gives callers control about which part
of the obligation to clone -- and takes advantage of the change to avoid
cloning the `Vec<Ty>`. The change speeds up runs of a few rustc-perf
benchmarks, the best by 1%.
@nnethercote
Copy link
Contributor Author

That Clone bound isn't necessary anymore

Good catch. I've updated to remove it.

@@ -257,7 +256,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let expected_kind = fulfillment_cx
.pending_obligations()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my grepping is accurate, these are the only two call sites. Since both call iter() on the resultant vector, can we not change the method to return an iterator directly, instead of collecting?

Further, I feel like we might be able to avoid cloning the obligation entirely, since iter() would only give reference-based access to it anyway...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that originally, but hit this error: "impl Trait not allowed outside of function and inherent method return types".

Because pending_obligations is a method of the TraitEngine trait.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, unfortunate. If this is hot enough, we could write a struct that implements iterator... but I'm not sure it's worth it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this patch got most of the potential gain.

@estebank
Copy link
Contributor

estebank commented Jun 8, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Jun 8, 2018

📌 Commit b0440d3 has been approved by estebank

@bors bors 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 Jun 8, 2018
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jun 8, 2018
…estebank

Avoid useless Vec clones in pending_obligations().

The only instance of `ObligationForest` in use has an obligation type of
`PendingPredicateObligation`, which contains a `PredicateObligation` and a
`Vec<Ty>`.

`FulfillmentContext::pending_obligations()` calls
`ObligationForest::pending_obligations()`, which clones all the
`PendingPredicateObligation`s. But the `Vec<Ty>` field of those cloned
obligations is never touched.

This patch changes `ObligationForest::pending_obligations()` to
`map_pending_obligations` -- which gives callers control about which part
of the obligation to clone -- and takes advantage of the change to avoid
cloning the `Vec<Ty>`. The change speeds up runs of a few rustc-perf
benchmarks, the best by 1%.
bors added a commit that referenced this pull request Jun 8, 2018
Rollup of 13 pull requests

Successful merges:

 - #50143 (Add deprecation lint for duplicated `macro_export`s)
 - #51099 (Fix Issue 38777)
 - #51276 (Dedup auto traits in trait objects.)
 - #51298 (Stabilize unit tests with non-`()` return type)
 - #51360 (Suggest parentheses when a struct literal needs them)
 - #51391 (Use spans pointing at the inside of a rustdoc attribute)
 - #51394 (Use scope tree depths to speed up `nearest_common_ancestor`.)
 - #51396 (Make the size of Option<NonZero*> a documented guarantee.)
 - #51401 (Warn on `repr` without hints)
 - #51412 (Avoid useless Vec clones in pending_obligations().)
 - #51427 (compiletest: autoremove duplicate .nll.* files (#51204))
 - #51436 (Do not require stage 2 compiler for rustdoc)
 - #51437 (rustbuild: generate full list of dependencies for metadata)

Failed merges:
@bors bors merged commit b0440d3 into rust-lang:master Jun 9, 2018
@nnethercote nnethercote deleted the pending_obligations branch June 9, 2018 02:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants