From ebf6d5aee6bbb986289ec772e61d7c38d0f75f01 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 29 Aug 2019 11:41:06 -0700 Subject: [PATCH] Fix performance regression in test classloader In 5eab9df0df60a14bf8e219ddfc149636bd59206f, I updated the outputFileStamps task to compute all of the stamps for a directory recursively if an output file is a directory. Prior to that, it had only computed the stamp for the directory itself. This caused a significant performance regression in creating the test classloader because it was computing the last modified time for all of the classfiles in the class path. The test for 5000 source files in https://github.com/eatkins/scala-build-watch-performance was running roughly 400ms slower due to this regression. --- main/src/main/scala/sbt/Defaults.scala | 1 - main/src/main/scala/sbt/internal/ClassLoaders.scala | 5 ++++- main/src/main/scala/sbt/nio/Keys.scala | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index d5085ad8f..c8062c48f 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2041,7 +2041,6 @@ object Classpaths { excludeFilter in unmanagedJars value ) ).map(exportClasspath) ++ Seq( - sbt.nio.Keys.classpathFiles := data(fullClasspath.value).map(_.toPath), sbt.nio.Keys.dependencyClasspathFiles := data(dependencyClasspath.value).map(_.toPath), ) diff --git a/main/src/main/scala/sbt/internal/ClassLoaders.scala b/main/src/main/scala/sbt/internal/ClassLoaders.scala index 4c01831bb..6ecc8b10e 100644 --- a/main/src/main/scala/sbt/internal/ClassLoaders.scala +++ b/main/src/main/scala/sbt/internal/ClassLoaders.scala @@ -30,7 +30,10 @@ private[sbt] object ClassLoaders { */ private[sbt] def testTask: Def.Initialize[Task[ClassLoader]] = Def.task { val si = scalaInstance.value - val rawCP = modifiedTimes((outputFileStamps in classpathFiles).value) + val cp = fullClasspath.value.map(_.data) + val dependencyStamps = modifiedTimes((outputFileStamps in dependencyClasspathFiles).value).toMap + def getLm(f: File): Long = dependencyStamps.getOrElse(f, IO.getModifiedTimeOrZero(f)) + val rawCP = cp.map(f => f -> getLm(f)) val fullCP = if (si.isManagedVersion) rawCP else si.libraryJars.map(j => j -> IO.getModifiedTimeOrZero(j)).toSeq ++ rawCP diff --git a/main/src/main/scala/sbt/nio/Keys.scala b/main/src/main/scala/sbt/nio/Keys.scala index 24983771e..32ec1721d 100644 --- a/main/src/main/scala/sbt/nio/Keys.scala +++ b/main/src/main/scala/sbt/nio/Keys.scala @@ -165,8 +165,6 @@ object Keys { .withRank(Invisible) private[sbt] val dependencyClasspathFiles = taskKey[Seq[Path]]("The dependency classpath for a task.").withRank(Invisible) - private[sbt] val classpathFiles = - taskKey[Seq[Path]]("The classpath for a task.").withRank(Invisible) private[sbt] val compileOutputs = taskKey[Seq[Path]]("Compilation outputs").withRank(Invisible) private[sbt] val compileSourceFileInputs = taskKey[Map[String, Seq[(Path, FileStamp)]]]("Source file stamps stored by scala version")