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

Add a "cheap" mode for compute_missing_ctors. #55167

Merged
merged 1 commit into from
Oct 26, 2018

Conversation

nnethercote
Copy link
Contributor

compute_missing_ctors produces a vector. It is called a lot, but the
vector is almost always only checked for emptiness.

This commit introduces a specialized variant of compute_missing_ctors
(called is_missing_ctors_empty) that determines if the resulting set
would be empty, and changes the callsite so that compute_missing_ctors
is only called in the rare cases where it is needed. The code
duplication is unfortunate but I can't see a better way to do it.

This change reduces instruction counts for several benchmarks up to 2%.

r? @varkor

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 18, 2018
@nnethercote
Copy link
Contributor Author

Some local benchmarking results:

helloworld-check
        avg: -1.9%      min: -2.0%      max: -1.7%
ctfe-stress-check
        avg: -0.9%?     min: -1.9%?     max: 0.5%?
unify-linearly-check
        avg: -1.3%      min: -1.8%      max: -0.9%
deeply-nested-check
        avg: -1.1%      min: -1.7%      max: -0.9%
issue-46449-check
        avg: -1.2%      min: -1.4%      max: -0.8%
coercions-check
        avg: 0.0%?      min: -1.0%?     max: 1.0%?
style-servo-check
        avg: -0.5%      min: -1.0%      max: 0.0%

@varkor
Copy link
Member

varkor commented Oct 18, 2018

This is a nice performance win, but I'm hesitant about just duplicating the logic. What do you think about changing the return type of compute_missing_ctors to:

enum MissingCtors<'tcx> {
	Empty,
	Nonempty,
	NonemptyWithCtors(Vec<Constructor<'tcx>>),
}

and then passing an extra parameter to compute_missing_ctors that determines whether to construct the vector, or to just use Nonempty?

@nnethercote
Copy link
Contributor Author

Ok, I can do that tomorrow.

@nnethercote nnethercote changed the title Add is_missing_ctors_empty. Add a "cheap" mode for compute_missing_ctors. Oct 19, 2018
@nnethercote
Copy link
Contributor Author

@varkor: I've updated the code as requested.

// Return a set of constructors equivalent to `all_ctors \ used_ctors`.
// Used by `compute_missing_ctors`.
#[derive(PartialEq)]
enum Cost {
Copy link
Member

Choose a reason for hiding this comment

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

I feel naming the variants of the function in terms of cost, rather than behaviour, is unhelpful — you can't guess what difference in behaviour might result from providing Cheap rather than Expensive (even if that is the motivation for the change). I'd rather stick with the comment about performance above compute_missing_ctors and give the variants more descriptive names.

@varkor
Copy link
Member

varkor commented Oct 19, 2018

r=me after the comment about naming. Thanks for investigating this!

@nnethercote
Copy link
Contributor Author

What names do you suggest instead of Cost, Cheap, Expensive, and the new parameter to missing_costs?

@varkor
Copy link
Member

varkor commented Oct 22, 2018

(Sorry, GitHub's been preventing me from commenting.)

Perhaps something like the following for the input, with #55167 (comment) as the output.

/// A request for missing constructor data in terms of either:
///	(a) Simply whether there are any missing constructors.
///	(b) Exactly which constructors are missing.
/// This is to improve performance in cases where the full constructor information is unnecessary.
enum MissingCtorsInfo {
	/// Corresponds to `MissingCtors::Empty` and `MissingCtors::Nonempty`.
	Emptiness,
	/// Corresponds to `MissingCtors::NonemptyWithCtors`.
	Ctors,
}

@nnethercote
Copy link
Contributor Author

Ok, but I'll change NonemptyWithCtors, because it can be empty.

`compute_missing_ctors` is called a lot. It produces a vector, which can
be reasonably large (e.g. 100+ elements), but the vector is almost
always only checked for emptiness.

This commit changes `compute_missing_ctors` so it can be called in a
cheap way that just indicates if the vector would be empty. If
necessary, the function can subsequently be called in an expensive way
to compute the full vector.

This change reduces instruction counts for several benchmarks up to 2%.
@nnethercote
Copy link
Contributor Author

Updated as requested.

@varkor
Copy link
Member

varkor commented Oct 22, 2018

Thanks for looking into this! @bors r+

@bors
Copy link
Contributor

bors commented Oct 22, 2018

📌 Commit b5336c0 has been approved by varkor

@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 Oct 22, 2018
kennytm added a commit to kennytm/rust that referenced this pull request Oct 24, 2018
… r=varkor

Add a "cheap" mode for `compute_missing_ctors`.

`compute_missing_ctors` produces a vector. It is called a lot, but the
vector is almost always only checked for emptiness.

This commit introduces a specialized variant of `compute_missing_ctors`
(called `is_missing_ctors_empty`) that determines if the resulting set
would be empty, and changes the callsite so that `compute_missing_ctors`
is only called in the rare cases where it is needed. The code
duplication is unfortunate but I can't see a better way to do it.

This change reduces instruction counts for several benchmarks up to 2%.

r? @varkor
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Oct 25, 2018
… r=varkor

Add a "cheap" mode for `compute_missing_ctors`.

`compute_missing_ctors` produces a vector. It is called a lot, but the
vector is almost always only checked for emptiness.

This commit introduces a specialized variant of `compute_missing_ctors`
(called `is_missing_ctors_empty`) that determines if the resulting set
would be empty, and changes the callsite so that `compute_missing_ctors`
is only called in the rare cases where it is needed. The code
duplication is unfortunate but I can't see a better way to do it.

This change reduces instruction counts for several benchmarks up to 2%.

r? @varkor
kennytm added a commit to kennytm/rust that referenced this pull request Oct 26, 2018
… r=varkor

Add a "cheap" mode for `compute_missing_ctors`.

`compute_missing_ctors` produces a vector. It is called a lot, but the
vector is almost always only checked for emptiness.

This commit introduces a specialized variant of `compute_missing_ctors`
(called `is_missing_ctors_empty`) that determines if the resulting set
would be empty, and changes the callsite so that `compute_missing_ctors`
is only called in the rare cases where it is needed. The code
duplication is unfortunate but I can't see a better way to do it.

This change reduces instruction counts for several benchmarks up to 2%.

r? @varkor
kennytm added a commit to kennytm/rust that referenced this pull request Oct 26, 2018
… r=varkor

Add a "cheap" mode for `compute_missing_ctors`.

`compute_missing_ctors` produces a vector. It is called a lot, but the
vector is almost always only checked for emptiness.

This commit introduces a specialized variant of `compute_missing_ctors`
(called `is_missing_ctors_empty`) that determines if the resulting set
would be empty, and changes the callsite so that `compute_missing_ctors`
is only called in the rare cases where it is needed. The code
duplication is unfortunate but I can't see a better way to do it.

This change reduces instruction counts for several benchmarks up to 2%.

r? @varkor
bors added a commit that referenced this pull request Oct 26, 2018
Rollup of 21 pull requests

Successful merges:

 - #54816 (Don't try to promote already promoted out temporaries)
 - #54824 (Cleanup rustdoc tests with `@!has` and `@!matches`)
 - #54921 (Add line numbers option to rustdoc)
 - #55167 (Add a "cheap" mode for `compute_missing_ctors`.)
 - #55258 (Fix Rustdoc ICE when checking blanket impls)
 - #55264 (Compile the libstd we distribute with -Ccodegen-unit=1)
 - #55271 (Unimplement ExactSizeIterator for MIR traversing iterators)
 - #55292 (Macro diagnostics tweaks)
 - #55298 (Point at macro definition when no rules expect token)
 - #55301 (List allowed tokens after macro fragments)
 - #55302 (Extend the impl_stable_hash_for! macro for miri.)
 - #55325 (Fix link to macros chapter)
 - #55343 (rustbuild: fix remap-debuginfo when building a release)
 - #55346 (Shrink `Statement`.)
 - #55358 (Remove redundant clone (2))
 - #55370 (Update mailmap for estebank)
 - #55375 (Typo fixes in configure_cmake comments)
 - #55378 (rustbuild: use configured linker to build boostrap)
 - #55379 (validity: assert that unions are non-empty)
 - #55383 (Use `SmallVec` for the queue in `coerce_unsized`.)
 - #55391 (bootstrap: clean up a few clippy findings)
@bors bors merged commit b5336c0 into rust-lang:master Oct 26, 2018
@nnethercote nnethercote deleted the is_missing_ctors_empty branch December 12, 2018 04:43
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.

4 participants