-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Always cache Attribute compatibility and disambiguation rules #30134
Conversation
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.
@bot-gradle test apt |
I've triggered the following builds for you. Click here to see all build failures. |
Avoid using a stream when matching attribute values Avoid using immutable list, as the hash map work was obvious
@bot-gradle test apt |
I've triggered the following builds for you. Click here to see all build failures. |
|
@@ -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(); |
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.
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 ResolvedVariant
s
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.
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.
It showed up in the flamegraphs
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.
The set operations, implemented by hashing, are not free
We will not always cache these since we want to enforce statelessness of the rules. Instad, we will:
|
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
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