summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-02-25 13:51:50 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-02-25 13:51:50 -0800
commit554840f9b5cd30a8e3209cb18bdf9925f364cc68 (patch)
treec573183911e02b89ff21c806def8a1b5ce0d9b46 /core
parent19219cbbd18efb819e45b0af221f08065ad5c982 (diff)
downloadmill-554840f9b5cd30a8e3209cb18bdf9925f364cc68.tar.gz
mill-554840f9b5cd30a8e3209cb18bdf9925f364cc68.tar.bz2
mill-554840f9b5cd30a8e3209cb18bdf9925f364cc68.zip
A few attempts at micro-optimizing the current hot spots
Diffstat (limited to 'core')
-rw-r--r--core/src/mill/define/Module.scala31
-rw-r--r--core/src/mill/eval/Evaluator.scala22
-rw-r--r--core/src/mill/eval/Result.scala4
-rw-r--r--core/src/mill/util/Logger.scala2
4 files changed, 36 insertions, 23 deletions
diff --git a/core/src/mill/define/Module.scala b/core/src/mill/define/Module.scala
index 93537f76..0f8e96ce 100644
--- a/core/src/mill/define/Module.scala
+++ b/core/src/mill/define/Module.scala
@@ -56,22 +56,25 @@ object Module{
lazy val millModuleLine = outer.millOuterCtx.lineNum
def reflect[T: ClassTag] = {
- outer
- .getClass
- .getMethods
- .filter(!_.getName.contains('$'))
- .filter(_.getParameterCount == 0)
- .filter(x => (x.getModifiers & Modifier.STATIC) == 0)
- .filter(implicitly[ClassTag[T]].runtimeClass isAssignableFrom _.getReturnType)
- .map(_.invoke(outer).asInstanceOf[T])
+ val runtimeCls = implicitly[ClassTag[T]].runtimeClass
+ for{
+ m <- outer.getClass.getMethods
+ if
+ !m.getName.contains('$') &&
+ m.getParameterCount == 0 &&
+ (m.getModifiers & Modifier.STATIC) == 0 &&
+ runtimeCls.isAssignableFrom(m.getReturnType)
+ } yield m.invoke(outer).asInstanceOf[T]
+
}
def reflectNames[T: ClassTag] = {
- outer
- .getClass
- .getMethods
- .filter(x => (x.getModifiers & Modifier.STATIC) == 0)
- .filter(implicitly[ClassTag[T]].runtimeClass isAssignableFrom _.getReturnType)
- .map(_.getName)
+ val runtimeCls = implicitly[ClassTag[T]].runtimeClass
+ for{
+ m <- outer.getClass.getMethods
+ if
+ (m.getModifiers & Modifier.STATIC) == 0 &&
+ runtimeCls.isAssignableFrom(m.getReturnType)
+ } yield m.getName
}
// For some reason, this fails to pick up concrete `object`s nested directly within
// another top-level concrete `object`. This is fine for now, since Mill's Ammonite
diff --git a/core/src/mill/eval/Evaluator.scala b/core/src/mill/eval/Evaluator.scala
index 57d39a24..42015c6f 100644
--- a/core/src/mill/eval/Evaluator.scala
+++ b/core/src/mill/eval/Evaluator.scala
@@ -32,7 +32,7 @@ case class Evaluator[T](outPath: Path,
log: Logger,
classLoaderSig: Seq[(Path, Long)] = Evaluator.classLoaderSig,
workerCache: mutable.Map[Segments, (Int, Any)] = mutable.Map.empty){
-
+ val classLoaderSignHash = classLoaderSig.hashCode()
def evaluate(goals: Agg[Task[_]]): Evaluator.Results = {
mkdir(outPath)
@@ -82,7 +82,12 @@ case class Evaluator[T](outPath: Path,
for (((terminal, group), i) <- sortedGroups.items().zipWithIndex){
// Increment the counter message by 1 to go from 1/10 to 10/10 instead of 0/10 to 9/10
val counterMsg = (i+1) + "/" + sortedGroups.keyCount
- val (newResults, newEvaluated) = evaluateGroupCached(terminal, group, results, counterMsg)
+ val (newResults, newEvaluated) = evaluateGroupCached(
+ terminal,
+ group,
+ results,
+ counterMsg)
+
for(ev <- newEvaluated){
evaluated.append(ev)
}
@@ -114,13 +119,16 @@ case class Evaluator[T](outPath: Path,
results: collection.Map[Task[_], Result[(Any, Int)]],
counterMsg: String): (collection.Map[Task[_], Result[(Any, Int)]], Seq[Task[_]]) = {
+ val externalInputsHash = scala.util.hashing.MurmurHash3.orderedHash(
+ group.items.flatMap(_.inputs).filter(!group.contains(_))
+ .flatMap(results(_).asSuccess.map(_.value._2))
+ )
- val externalInputs = group.items.flatMap(_.inputs).filter(!group.contains(_)).toVector
+ val sideHashes = scala.util.hashing.MurmurHash3.orderedHash(
+ group.toIterator.map(_.sideHash)
+ )
- val inputsHash =
- externalInputs.map(results(_).map(_._2)).hashCode +
- group.toIterator.map(_.sideHash).toVector.hashCode() +
- classLoaderSig.hashCode()
+ val inputsHash = externalInputsHash + sideHashes + classLoaderSignHash
terminal match{
case Left(task) =>
diff --git a/core/src/mill/eval/Result.scala b/core/src/mill/eval/Result.scala
index 690c5d30..d0400599 100644
--- a/core/src/mill/eval/Result.scala
+++ b/core/src/mill/eval/Result.scala
@@ -2,14 +2,16 @@ package mill.eval
sealed trait Result[+T]{
def map[V](f: T => V): Result[V]
+ def asSuccess: Option[Result.Success[T]] = None
}
object Result{
implicit def create[T](t: => T): Result[T] = {
try Success(t)
catch { case e: Throwable => Exception(e, new OuterStack(new java.lang.Exception().getStackTrace)) }
}
- case class Success[T](value: T) extends Result[T]{
+ case class Success[+T](value: T) extends Result[T]{
def map[V](f: T => V) = Result.Success(f(value))
+ override def asSuccess = Some(this)
}
case object Skipped extends Result[Nothing]{
def map[V](f: Nothing => V) = this
diff --git a/core/src/mill/util/Logger.scala b/core/src/mill/util/Logger.scala
index 55ea84cc..714b9add 100644
--- a/core/src/mill/util/Logger.scala
+++ b/core/src/mill/util/Logger.scala
@@ -136,7 +136,7 @@ case class FileLogger(colored: Boolean, file: Path) extends Logger {
def info(s: String) = outputStream.println(s)
def error(s: String) = outputStream.println(s)
def ticker(s: String) = outputStream.println(s)
- val inStream: InputStream = new ByteArrayInputStream(Array())
+ val inStream: InputStream = DummyInputStream
override def close() = {
if (outputStreamUsed)
outputStream.close()