From 1ae3bc3ab17e9e8b60a57fff682768967ba9a251 Mon Sep 17 00:00:00 2001 From: Todor Petrov Date: Sun, 19 May 2019 00:03:17 +0300 Subject: [PATCH 1/2] Two performance fixes without which the build takes minutes in the configuration phase for multi-module projects with a lot of cross-references. 1. Loads the plugin just one time, instead of loading separately for each module. Debug logging showed that sometimes, this operations takes 10 sec (on some machines at least). 2. The more critical issue was in `recursiveDependenciesOf`. Without caching of the results, the same operations are repeated over and over again and it takes minutes to configure. For a work project I have, with 16 modules, with a lot of cross-references, adding the scoverage plugin without these fixes takes 5-10 mins. The worst of it is that this is the wait time for each change in any build.gradle (e.g. adding a new dependency), which makes the work nearly impossible. After applying the fixes, there is no significant difference with the time taken without the scoverage plugin. --- .../org/scoverage/ScoveragePlugin.groovy | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy index 7c6ac63..62e3562 100644 --- a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy +++ b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy @@ -10,6 +10,7 @@ import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.scala.ScalaCompile import java.nio.file.Files +import java.util.concurrent.ConcurrentHashMap import static groovy.io.FileType.FILES @@ -23,6 +24,9 @@ class ScoveragePlugin implements Plugin { static final String DEFAULT_REPORT_DIR = 'reports' + File.separatorChar + 'scoverage' + private volatile File pluginFile = null + private ConcurrentHashMap> taskDependencies = new ConcurrentHashMap<>(); + @Override void apply(PluginAware pluginAware) { if (pluginAware instanceof Project) { @@ -174,9 +178,12 @@ class ScoveragePlugin implements Plugin { } compileTask.configure { - File pluginFile = project.configurations[CONFIGURATION_NAME].find { - it.name.startsWith("scalac-scoverage-plugin") + if (pluginFile == null) { + pluginFile = project.configurations[CONFIGURATION_NAME].find { + it.name.startsWith("scalac-scoverage-plugin") + } } + List parameters = ['-Xplugin:' + pluginFile.absolutePath] List existingParameters = scalaCompileOptions.additionalParameters if (existingParameters) { @@ -269,9 +276,15 @@ class ScoveragePlugin implements Plugin { } private Set recursiveDependenciesOf(Task task) { + if (!taskDependencies.containsKey(task)) { + def directDependencies = task.getTaskDependencies().getDependencies(task) + def nestedDependencies = directDependencies.collect {recursiveDependenciesOf(it) }.flatten() + def dependencies = directDependencies + nestedDependencies - def directDependencies = task.getTaskDependencies().getDependencies(task) - def nestedDependencies = directDependencies.collect {recursiveDependenciesOf(it) }.flatten() - return directDependencies + nestedDependencies + taskDependencies.put(task, dependencies) + return dependencies + } else { + return taskDependencies.get(task) + } } } \ No newline at end of file From 7e7e792a84920473292c8a0b9197ea16aa7f4eea Mon Sep 17 00:00:00 2001 From: Todor Petrov Date: Mon, 20 May 2019 12:56:00 +0300 Subject: [PATCH 2/2] Made the task dependencies cache final. --- src/main/groovy/org/scoverage/ScoveragePlugin.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy index 62e3562..b72a130 100644 --- a/src/main/groovy/org/scoverage/ScoveragePlugin.groovy +++ b/src/main/groovy/org/scoverage/ScoveragePlugin.groovy @@ -25,7 +25,7 @@ class ScoveragePlugin implements Plugin { static final String DEFAULT_REPORT_DIR = 'reports' + File.separatorChar + 'scoverage' private volatile File pluginFile = null - private ConcurrentHashMap> taskDependencies = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> taskDependencies = new ConcurrentHashMap<>(); @Override void apply(PluginAware pluginAware) {