Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
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 (#2), then calls `SnapshotMap::insert`. - `insert` does *another* cache lookup (#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 #2. Furthermore, if the `NormalizedTy`'s obligations are empty (the common case), we know that lookup #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![]; | |||
Mark-Simulacrum
May 17, 2018
Member
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.
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.
nnethercote
May 17, 2018
Author
Contributor
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.
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+ |
|
|
|
@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_typeis 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%.