Add fast paths to PrerequisiteArtifacts.get(). Most often,
ruleContext.getPrerequisites() returns 0 or 1 FileProvider instance. In these
cases, there is no need to ever create a HashSet for deduplication.
RELNOTES: None.
@@ -44,9 +44,23 @@ public final class PrerequisiteArtifacts {
}
static PrerequisiteArtifacts get(RuleContext ruleContext, String attributeName, Mode mode) {
+ ImmutableList<FileProvider> prerequisites =
+ ImmutableList.copyOf(ruleContext.getPrerequisites(attributeName, mode, FileProvider.class));
+ // Fast path #1: Many attributes are not set.
+ if (prerequisites.isEmpty()) {
+ return new PrerequisiteArtifacts(ruleContext, attributeName, ImmutableList.of());
+ }
+ // Fast path #2: Often, attributes are set exactly once. In this case, we can completely elide
+ // additional copies as the getFilesToBuild() call already returns an ImmutableList of the
+ // expanded NestedSet.
+ if (prerequisites.size() == 1) {
+ return new PrerequisiteArtifacts(
+ ruleContext,
+ attributeName,
+ ImmutableList.copyOf(prerequisites.get(0).getFilesToBuild().toList()));
+ }
Set<Artifact> result = new LinkedHashSet<>();
- for (FileProvider target :
- ruleContext.getPrerequisites(attributeName, mode, FileProvider.class)) {
+ for (FileProvider target : prerequisites) {
Iterables.addAll(result, target.getFilesToBuild());
}
return new PrerequisiteArtifacts(ruleContext, attributeName, ImmutableList.copyOf(result));
