From f27b3080e8e16bf755661e89a12dc4daf681f787 Mon Sep 17 00:00:00 2001 From: "Alexander.Glukhov" Date: Mon, 29 Jul 2024 15:30:30 +0200 Subject: [PATCH] [gradle][IDEA-356858] added a caching layer into `GradleExtensionsSettings#Settings` to prevent unnecessary allocations GitOrigin-RevId: 2b52bf35c0433e7632394decade6cbe53eb6c337 --- .../settings/GradleExtensionsSettings.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java index 5daf091a8172..1aaa10a7056e 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/settings/GradleExtensionsSettings.java @@ -18,9 +18,7 @@ import com.intellij.psi.PsiFile; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.*; -import org.jetbrains.plugins.gradle.model.ExternalTask; -import org.jetbrains.plugins.gradle.model.GradleExtensions; -import org.jetbrains.plugins.gradle.model.GradleProperty; +import org.jetbrains.plugins.gradle.model.*; import org.jetbrains.plugins.gradle.service.project.data.GradleExtensionsDataService; import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames; import org.jetbrains.plugins.gradle.util.GradleConstants; @@ -77,7 +75,6 @@ public class GradleExtensionsSettings { public static class Settings { private final @NotNull Map projects = new HashMap<>(); - private final @NotNull GradleExtensionDataFactory extensionDataFactory = new GradleExtensionDataFactory(); public void add(@NotNull String rootPath, @NotNull Collection> extensionsData) { @@ -95,8 +92,9 @@ public class GradleExtensionsSettings { public void add(@NotNull String rootPath, @NotNull Map extensions) { GradleProject gradleProject = new GradleProject(); + GradleExtensionDataFactory factory = new GradleExtensionDataFactory(); for (Map.Entry entry : extensions.entrySet()) { - GradleExtensionsData extensionsData = extensionDataFactory.getGradleExtensionsData(entry.getValue(), gradleProject); + GradleExtensionsData extensionsData = factory.getGradleExtensionsData(entry.getValue(), gradleProject); gradleProject.extensions.put(entry.getKey(), extensionsData); } projects.put(rootPath, gradleProject); @@ -220,36 +218,62 @@ public class GradleExtensionsSettings { private static class GradleExtensionDataFactory { + private final @NotNull Map extensionCache = new HashMap<>(); + private final @NotNull Map conventionCache = new HashMap<>(); + private final @NotNull Map propertyCache = new HashMap<>(); + // Task name + fqdn -> GradleTask. + // We're not interested in the task description because it will lead to a cache miss in the majority of cases. + private final @NotNull Map taskCache = new HashMap<>(); + private final @NotNull Map configurationCache = new HashMap<>(); + + /** + * It is safe to cache GradleExtensionsData. + * All the extension data objects are parts of the same GradleProject. + */ + private final @NotNull Map gradleExtensionsCache = new HashMap<>(); + public @NotNull GradleExtensionsData getGradleExtensionsData(@NotNull GradleExtensions gradleExtensions, @NotNull GradleProject gradleProject) { + return gradleExtensionsCache.computeIfAbsent( + (DefaultGradleExtensions)gradleExtensions, + e -> convertGradleExtensionsData(e, gradleProject) + ); + } + + private @NotNull GradleExtensionsData convertGradleExtensionsData(@NotNull GradleExtensions gradleExtensions, + @NotNull GradleProject gradleProject) { Map extensions = new HashMap<>(); for (org.jetbrains.plugins.gradle.model.GradleExtension extension : gradleExtensions.getExtensions()) { - GradleExtension gradleExtension = convertGradleExtension(extension); + GradleExtension gradleExtension = extensionCache.computeIfAbsent((DefaultGradleExtension)extension, + GradleExtensionDataFactory::convertGradleExtension); extensions.put(gradleExtension.getName(), gradleExtension); } List conventions = new SmartList<>(); for (org.jetbrains.plugins.gradle.model.GradleConvention convention : gradleExtensions.getConventions()) { - GradleConvention gradleConvention = convertGradleConvention(convention); + GradleConvention gradleConvention = conventionCache.computeIfAbsent((DefaultGradleConvention)convention, + GradleExtensionDataFactory::convertGradleConvention); conventions.add(gradleConvention); } Map properties = new HashMap<>(); for (GradleProperty property : gradleExtensions.getGradleProperties()) { - GradleProp gradleProp = convertGradleProp(property); + GradleProp gradleProp = propertyCache.computeIfAbsent((DefaultGradleProperty)property, + GradleExtensionDataFactory::convertGradleProp); properties.put(gradleProp.getName(), gradleProp); } Map tasksMap = new LinkedHashMap<>(); for (ExternalTask task : gradleExtensions.getTasks()) { - GradleTask gradleTask = convertGradleTask(task); + GradleTask gradleTask = taskCache.computeIfAbsent(task.getName() + task.getType(), __ -> convertGradleTask(task)); tasksMap.put(gradleTask.getName(), gradleTask); } Map configurations = new HashMap<>(); Map buildScriptConfigurations = new HashMap<>(); for (org.jetbrains.plugins.gradle.model.GradleConfiguration configuration : gradleExtensions.getConfigurations()) { - GradleConfiguration gradleConfiguration = convertGradleConfiguration(configuration); + GradleConfiguration gradleConfiguration = configurationCache.computeIfAbsent((DefaultGradleConfiguration)configuration, + GradleExtensionDataFactory::convertGradleConfiguration); if (gradleConfiguration.scriptClasspath) { buildScriptConfigurations.put(gradleConfiguration.getName(), gradleConfiguration); }