From be49752855a1a6997d4112eeff351e1c119a8a93 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 11 Mar 2011 12:13:58 +0000 Subject: A patch for views. Most relevant change: Almost all view classes now list parents like trait Appended[B >: A] extends super.Appended[B] with Transformed[B] instead of the former trait Appended[B >: A] extends Transformed[B] with super.Appended[B] because as it was, the implementation of foreach in TraversableViewLike#Transformed was repeatedly trumping overrides found in e.g. IterableLike. This change was not without its own consequences, and much of the rest of the patch is dealing with that. A more general issue is clearly revealed here: there is no straightforward way to deal with trait composition and overrides when some methods should prefer B over A and some the reverse. (It's more like A through Z in this case.) That closes #4279, with some views being five orders of magnitude slower than necessary. There is a test that confirms they'll stay performance neighbors. In the view classes (Zipped, Mapped, etc.) I attended to them with comb and brush until they were reasonably consistent. I only use "override" where necessary and throw in some "final" in the interests of trying to anchor the composition outcome. I also switched the newSliced, newZipped, etc. methods to use early init syntax since a number have abstract vals and I found at least one bug originating with uninitialized access. There was a piece of a parallel collections scalacheck test failing, which I disabled out of expedience - am emailing prokopec. There is plenty of work left to do but paulp must get back to other 2.9 issues. This is the Zurich->SF airplane patch. No review. --- test/files/run/view-iterator-stream.scala | 67 +++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 test/files/run/view-iterator-stream.scala (limited to 'test/files/run/view-iterator-stream.scala') diff --git a/test/files/run/view-iterator-stream.scala b/test/files/run/view-iterator-stream.scala new file mode 100644 index 0000000000..5ac299a34d --- /dev/null +++ b/test/files/run/view-iterator-stream.scala @@ -0,0 +1,67 @@ +import scala.collection.{ mutable, immutable, generic } +import collection.TraversableView + +object Test { + type PerturberFn[T] = TraversableOnce[T] => TraversableOnce[T] + lazy val Id = new Perturber(Nil, identity[TraversableOnce[Int]] _) { } + class Perturber(val labels: List[String], val f: PerturberFn[Int]) extends PerturberFn[Int] { + def apply(xs: TraversableOnce[Int]): TraversableOnce[Int] = f(xs) + def show(xs: TraversableOnce[Int]): String = { + val res = f(xs) + val resString = "" + res + val rest = res.toTraversable + val failed = (rest take 100).size == 100 + + "%-45s %-30s %s".format(toString, resString, + if (failed) "" else rest.mkString(" ") + ) + } + def and(g: Perturber): Perturber = + new Perturber(this.labels ++ g.labels, f andThen g.f) + + override def toString = labels mkString " -> " + } + object Perturber { + def apply(label: String, f: PerturberFn[Int]) = new Perturber(List(label), f) + } + + def naturals = Stream from 1 + val toV : Perturber = Perturber("view", _.toTraversable.view) + val toI : Perturber = Perturber("toIterator", _.toIterator) + val toS : Perturber = Perturber("toStream", _.toStream) + val toIS : Perturber = Perturber("toIndexedSeq", _.toIndexedSeq) + + def p(ps: Perturber*): Perturber = if (ps.isEmpty) Id else ps.reduceLeft(_ and _) + def drop(n: Int): Perturber = Perturber("drop " + n, _.toIterator drop n) + def take(n: Int): Perturber = Perturber("take " + n, _.toIterator take n) + def slice(from: Int, until: Int): Perturber = + Perturber( + "slice(%d, %d)".format(from, until), + _.toTraversable.slice(from, until) + ) + + val fns = List[Perturber](toV, toI, toS, toIS) + + def tds(n: Int): Perturber = p(drop(n), take(n / 2), slice(1, n / 4)) + def dts(n: Int): Perturber = p(take(n), drop(n / 2), slice(1, n / 4)) + def sdt(n: Int): Perturber = p(slice(n, n * 2), drop(n / 2), take(n / 4)) + def std(n: Int): Perturber = p(slice(n, n * 2), take(n / 2), drop(n / 4)) + + val transforms = (fns.permutations map (xs => p(xs take 3: _*))).toList.distinct + def mkOps(n: Int) = List[Perturber](tds(n), dts(n), sdt(n), std(n)) + def runOps(n: Int) = { + val xs: List[(String, List[String])] = mkOps(n) map { op => + ("" + op, transforms map (_ show op(naturals)) sorted) + } + for ((k, v) <- xs) { + println("\n** " + k + " **\n") + println("-------------------") + v foreach println + } + () + } + + def main(args: Array[String]): Unit = { + runOps(20) + } +} -- cgit v1.2.3