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

Always cache Attribute compatibility and disambiguation rules #30134

Closed

Conversation

jvandort
Copy link
Member

@jvandort jvandort commented Aug 9, 2024

Compatibility rules especially are called in tight loops in the middle of dependency resolution. We have seen builds that rely on custom rules heavily spend a huge amount of time during resolution instantiating these rules over and over.

This commit updates the rule instantiator to cache the value for the rule so that we do not waste time instantiating the rule over and over again.

We expect these rules to be deterministic. Both AGP and KGP rules were verified to be deterministic and not have side-effects in their constructors.

Fixes #30110

Running the Android 2000 project extra large benchmark with 10 iterations:

before:

Max: 71.0 seconds
Min: 60.5 seconds
Mean: 63.0 seconds
Median: 62.3 seconds

after:

Max: 63.4 seconds
Min: 53.8 seconds
Mean: 56.4 seconds
Median: 55.4 seconds

This gives an improvement of:

Max: 10.8%
Min: 11.1%
Mean: 10.5%
Median: 11.1%

This is clear looking a the flamegraphs of artifact selection for example
image
image

Artifact selection went from 10,842 samples to 6,646 samples, a 38.7% improvement

The raw flamegraphs themselves:

androidStudioSync-8 11-20240809025650+0000-cpu-simplified-flames
androidStudioSync-8 11-20240809022902+0000-cpu-simplified-flames

Reviewing cheatsheet

Before merging the PR, comments starting with

  • ❌ ❓must be fixed
  • 🤔 💅 should be fixed
  • 💭 may be fixed
  • 🎉 celebrate happy things

Compatibility rules especially are called in tight loops in the middle of dependency resolution.
We have seen builds that rely on custom rules heavily spend a huge amount of time during resolution
instantiating these rules over and over.

This commit updates the rule instantiator to cache the value for the rule so that we do not waste time
instantiating the rule over and over again.

We expect these rules to be deterministic. Both AGP and KGP rules were verified to be deterministic and
not have side-effects in their constructors.
@jvandort
Copy link
Member Author

jvandort commented Aug 9, 2024

@bot-gradle test apt

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.

@jvandort jvandort self-assigned this Aug 9, 2024
@jvandort jvandort added this to the 8.11 RC1 milestone Aug 9, 2024
Avoid using a stream when matching attribute values
Avoid using immutable list, as the hash map work was obvious
@jvandort
Copy link
Member Author

jvandort commented Aug 9, 2024

@bot-gradle test apt

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you. Click here to see all build failures.

@jvandort
Copy link
Member Author

jvandort commented Aug 9, 2024

  • We need to talk more about the impact of rules. Can we now live with allowing you to write rules that are stateful and can persist state between calls?
  • Do we enforce immutability by reflectively scanning the class?

@@ -44,7 +44,7 @@ public interface ResolvedVariantSet {
/**
* The variants available for artifact selection when variant reselection is not enabled.
*/
Set<ResolvedVariant> getVariants();
List<ResolvedVariant> getVariants();
Copy link
Member

Choose a reason for hiding this comment

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

Why are you changing this? Is this just to get rid of the as Set in the tests? List implies that you could have multiple equivalent ResolvedVariants

Some alternatives to that would be:

  • use toSet()
  • declare the type as a Set vs def

as Set is idiomatic Groovy, so I wouldn't really worry about that.

Copy link
Member Author

@jvandort jvandort Aug 9, 2024

Choose a reason for hiding this comment

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

It showed up in the flamegraphs

Copy link
Member Author

Choose a reason for hiding this comment

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

The set operations, implemented by hashing, are not free

@jvandort
Copy link
Member Author

We will not always cache these since we want to enforce statelessness of the rules.

Instad, we will:

  1. Use to improve instantiation performance
  2. Cache results of each rule call
  3. Hoist up attribute schema caches so we deduplicate caches between projects

@jvandort jvandort closed this Aug 13, 2024
@github-actions github-actions bot removed this from the 8.11 RC1 milestone Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically cache CompatibilityRule and DisambiguationRule instances
3 participants