From 418e7e09fd8c86c0e1a3d580ebd85b42be398639 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 13 May 2019 11:02:08 -0700 Subject: [PATCH] Shave O(500ms) off of sbt startup It turns out that it can take roughly one second to instantiate a scala.nsc.tools.Global instance for the first time. When sbt is starting up, it also takes nearly 2 seconds to initialize logging. We can speed up the boot time by doing these two things concurrently. On my machine, I saw on average a 500ms decrease in startup time after this change. --- main/src/main/scala/sbt/Main.scala | 8 ++++++++ main/src/main/scala/sbt/internal/parser/SbtParser.scala | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 05bdda9c1..134299a51 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -44,6 +44,14 @@ final class xMain extends xsbti.AppMain { val instance = clazz.getField("MODULE$").get(null) val runMethod = clazz.getMethod("run", classOf[xsbti.AppConfiguration]) try { + new Thread("sbt-load-global-instance") { + setDaemon(true) + override def run(): Unit = { + // This preloads the scala.tools.nsc.Global as a performance optimization" + loader.loadClass("sbt.internal.parser.SbtParser$").getField("MODULE$").get(null) + () + } + }.start() runMethod.invoke(instance, modifiedConfiguration).asInstanceOf[xsbti.MainResult] } catch { case e: InvocationTargetException => diff --git a/main/src/main/scala/sbt/internal/parser/SbtParser.scala b/main/src/main/scala/sbt/internal/parser/SbtParser.scala index 22020d30d..c6d0ac2ca 100644 --- a/main/src/main/scala/sbt/internal/parser/SbtParser.scala +++ b/main/src/main/scala/sbt/internal/parser/SbtParser.scala @@ -108,7 +108,7 @@ private[sbt] object SbtParser { private[sbt] final val globalReporter = new UniqueParserReporter private[sbt] var scalacGlobalInitReporter: Option[ConsoleReporter] = None - private[sbt] final lazy val defaultGlobalForParser = { + private[sbt] final val defaultGlobalForParser = { val options = "-cp" :: s"$defaultClasspath" :: "-Yrangepos" :: Nil val reportError = (msg: String) => System.err.println(msg) val command = new CompilerCommand(options, reportError)