-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Speed up opt_normalize_projection_type
#50818
Conversation
There is a hot path through `opt_normalize_projection_type`: - `try_start` does a cache lookup (#1). - The result is a `NormalizedTy`. - There are no unresolved type vars, so we call `complete`. - `complete` does *another* cache lookup (rust-lang#2), then calls `SnapshotMap::insert`. - `insert` does *another* cache lookup (rust-lang#3), inserting the same value that's already in the cache. This patch optimizes this hot path by introducing `complete_normalized`, for use when the value is known in advance to be a `NormalizedTy`. It always avoids lookup rust-lang#2. Furthermore, if the `NormalizedTy`'s obligations are empty (the common case), we know that lookup rust-lang#3 would be a no-op, so we avoid it, while inserting a Noop into the `SnapshotMap`'s undo log.
This patch changes `opt_normalize_project_type` so it appends obligations to a given obligations vector, instead of returning a new obligations vector. This change avoids lots of allocations. In the most extreme case, for a clean "Check" build of serde it reduces the total number of allocations by 20%.
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
@@ -202,17 +202,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { | |||
obligation.cause.span, | |||
infer::LateBoundRegionConversionTime::HigherRankedType, | |||
data); | |||
let normalized = super::normalize_projection_type( | |||
let mut obligations = vec![]; |
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.
If this specifically is hot, it'd be interesting to see if we could make this an Option
argument since obligations
appear to be unused in this case.
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.
This particular callsite is not hot. The hot callsite is the one within <TypeFolder for AssociatedTypeNormalizer>::fold_ty
in librustc/traits/project.rs
, which passes an existing vector.
@bors r+ |
📌 Commit 47bc774 has been approved by |
@bors rollup |
…omatsakis Speed up `opt_normalize_projection_type` `opt_normalize_projection_type` is hot in the serde and futures benchmarks in rustc-perf. These two patches speed up the execution of most runs for them by 2--4%.
Rollup of 10 pull requests Successful merges: - #50387 (Remove leftover tab in libtest outputs) - #50553 (Add Option::xor method) - #50610 (Improve format string errors) - #50649 (Tweak `nearest_common_ancestor()`.) - #50790 (Fix grammar documentation wrt Unicode identifiers) - #50791 (Fix null exclusions in grammar docs) - #50806 (Add `bless` x.py subcommand for easy ui test replacement) - #50818 (Speed up `opt_normalize_projection_type`) - #50837 (Revert #49767) - #50839 (Make sure people know the book is free oline) Failed merges:
opt_normalize_projection_type
is hot in the serde and futures benchmarks in rustc-perf. These two patches speed up the execution of most runs for them by 2--4%.