mirror of https://github.com/sbt/sbt.git
Optimize TupleMapExtension
This commit is contained in:
parent
e3449fff02
commit
57db671073
|
|
@ -313,8 +313,7 @@ object TaskExtra extends TaskExtra {
|
|||
if incs.isEmpty then in.unmap(Result.tryValue)
|
||||
else throw incompleteDeps(incs)
|
||||
}
|
||||
def failuresM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = x =>
|
||||
failures(x.iterator.toList)
|
||||
def failuresM[Tup <: Tuple]: Tuple.Map[Tup, Result] => Seq[Incomplete] = x => failures(x.toList0)
|
||||
|
||||
def all[D](in: Seq[Result[D]]): Seq[D] = {
|
||||
val incs = failures(in)
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ object Transform:
|
|||
)(f: Tuple.Map[Tup, Result] => Either[Task[A1], A1]): Node[A1] =
|
||||
new Node[A1]:
|
||||
type Inputs = Tuple.Map[Tup, Result]
|
||||
def dependencies: List[TaskId[?]] = deps.iterator.toList
|
||||
def dependencies: List[TaskId[?]] = deps.toList0
|
||||
def computeInputs(f: [a] => TaskId[a] => Result[a]) = deps.transform(f)
|
||||
def work(inputs: Inputs) = f(inputs)
|
||||
|
||||
|
|
|
|||
|
|
@ -801,7 +801,8 @@ trait Init[ScopeType]:
|
|||
(fa: Initialize[A]) => (fa.mapConstant(g))
|
||||
private[this] def evaluateK(g: Settings[ScopeType]): [A] => Initialize[A] => A = [A] =>
|
||||
(fa: Initialize[A]) => (fa.evaluate(g))
|
||||
private[this] def deps(ls: Seq[Initialize[_]]): Seq[ScopedKey[_]] = ls.flatMap(_.dependencies)
|
||||
private[this] def deps(ls: List[Initialize[_]]): Seq[ScopedKey[_]] =
|
||||
ls.flatMap(_.dependencies)
|
||||
|
||||
/**
|
||||
* An `Initialize[T]` associated with a `ScopedKey[S]`.
|
||||
|
|
@ -977,7 +978,7 @@ trait Init[ScopeType]:
|
|||
) extends Initialize[A1]:
|
||||
import sbt.internal.util.TupleMapExtension.*
|
||||
|
||||
override def dependencies: Seq[ScopedKey[_]] = deps(inputs.iterator.toList)
|
||||
override def dependencies: Seq[ScopedKey[_]] = deps(inputs.toList0)
|
||||
override def mapReferenced(g: MapScoped): Initialize[A1] =
|
||||
Apply(f, inputs.transform(mapReferencedK(g)))
|
||||
override def mapConstant(g: MapConstant): Initialize[A1] =
|
||||
|
|
@ -989,13 +990,13 @@ trait Init[ScopeType]:
|
|||
|
||||
override def validateKeyReferenced(g: ValidateKeyRef): ValidatedInit[A1] =
|
||||
val tx: Tuple.Map[Tup, ValidatedInit] = inputs.transform(validateKeyReferencedK(g))
|
||||
val undefs = tx.iterator.flatMap(_.left.toSeq.flatten)
|
||||
val undefs = tx.iterator.flatMap(_.left.getOrElse(Seq.empty))
|
||||
val get = [A] => (fa: ValidatedInit[A]) => fa.toOption.get
|
||||
if undefs.isEmpty then Right(Apply(f, tx.transform(get)))
|
||||
else Left(undefs.toSeq)
|
||||
|
||||
private[sbt] override def processAttributes[A2](init: A2)(f: (A2, AttributeMap) => A2): A2 =
|
||||
inputs.iterator.toList.foldLeft(init) { (v, i) => i.processAttributes(v)(f) }
|
||||
inputs.toList0.foldLeft(init) { (v, i) => i.processAttributes(v)(f) }
|
||||
end Apply
|
||||
|
||||
private def remove[A](s: Seq[A], v: A) = s.filterNot(_ == v)
|
||||
|
|
|
|||
|
|
@ -14,11 +14,46 @@ object TupleMapExtension:
|
|||
extension [Tup <: Tuple, F1[_]](tuple: Tuple.Map[Tup, F1])
|
||||
def iterator: Iterator[F1[Any]] = tuple.productIterator.asInstanceOf[Iterator[F1[Any]]]
|
||||
|
||||
def unmap(f: [a] => F1[a] => a): Tup =
|
||||
Tuple.fromArray(tuple.iterator.map(f(_)).toArray).asInstanceOf[Tup]
|
||||
// typed version of tuple.toList
|
||||
def toList0: List[F1[Any]] =
|
||||
tuple.iterator.toList.asInstanceOf[List[F1[Any]]]
|
||||
|
||||
def unmap(f: [a] => F1[a] => a): Tup = transform[[A] =>> A](f).asInstanceOf[Tup]
|
||||
def transform[F2[_]](f: [a] => F1[a] => F2[a]): Tuple.Map[Tup, F2] =
|
||||
Tuple.fromArray(tuple.iterator.map(f(_)).toArray).asInstanceOf[Tuple.Map[Tup, F2]]
|
||||
inline def f0(x: Any) = f(x.asInstanceOf[F1[Any]])
|
||||
// We could use tuple.map from the scala3-library but it creates temporary arrays
|
||||
// which has an impact on the performance.
|
||||
// Instead, for small tuples, of size under 22, we map over each element manually.
|
||||
// format: off
|
||||
val res = (tuple: Tuple) match
|
||||
case EmptyTuple => EmptyTuple
|
||||
case t: NonEmptyTuple =>
|
||||
t.size match
|
||||
case 1 => Tuple1(f0(t(0)))
|
||||
case 2 => (f0(t(0)), f0(t(1)))
|
||||
case 3 => (f0(t(0)), f0(t(1)), f0(t(2)))
|
||||
case 4 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)))
|
||||
case 5 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)))
|
||||
case 6 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)))
|
||||
case 7 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)))
|
||||
case 8 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)))
|
||||
case 9 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)))
|
||||
case 10 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)))
|
||||
case 11 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)))
|
||||
case 12 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)))
|
||||
case 13 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)))
|
||||
case 14 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)))
|
||||
case 15 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)))
|
||||
case 16 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)))
|
||||
case 17 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)))
|
||||
case 18 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)), f0(t(17)))
|
||||
case 19 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)), f0(t(17)), f0(t(18)))
|
||||
case 20 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)), f0(t(17)), f0(t(18)), f0(t(19)))
|
||||
case 21 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)), f0(t(17)), f0(t(18)), f0(t(19)), f0(t(20)))
|
||||
case 22 => (f0(t(0)), f0(t(1)), f0(t(2)), f0(t(3)), f0(t(4)), f0(t(5)), f0(t(6)), f0(t(7)), f0(t(8)), f0(t(9)), f0(t(10)), f0(t(11)), f0(t(12)), f0(t(13)), f0(t(14)), f0(t(15)), f0(t(16)), f0(t(17)), f0(t(18)), f0(t(19)), f0(t(20)), f0(t(21)))
|
||||
case _ => scala.runtime.TupleXXL.fromIterator(tuple.iterator.map(f(_)))
|
||||
// format: on
|
||||
res.asInstanceOf[Tuple.Map[Tup, F2]]
|
||||
|
||||
def traverse[F2[_]](f: [a] => F1[a] => F2[a])(using app: Applicative[F2]): F2[Tup] =
|
||||
val fxs: F2[List[Any]] = tuple.iterator
|
||||
|
|
|
|||
Loading…
Reference in New Issue