summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-04-20 20:43:37 +0000
committerPaul Phillips <paulp@improving.org>2011-04-20 20:43:37 +0000
commit21ea5ad62747504e2c17c10c779e5c7054a2a297 (patch)
tree8e3d4ac052ffd406d179da2694a9fd93724a4e13 /src
parent9be2e5463396e4a5022745c9d61a8431d53e2f99 (diff)
downloadscala-21ea5ad62747504e2c17c10c779e5c7054a2a297.tar.gz
scala-21ea5ad62747504e2c17c10c779e5c7054a2a297.tar.bz2
scala-21ea5ad62747504e2c17c10c779e5c7054a2a297.zip
One of the blips in the performance charts seem...
One of the blips in the performance charts seems to implicate some changes I made with slice to reduce the number of implementations and surface area for inconsistencies and bugs. Altering those changes in a more performance-mindful way, although I don't see anything here which is likely to help much. Also fixing some wrong documentation about copyToArray. No review.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala2
-rwxr-xr-xsrc/library/scala/collection/IndexedSeqOptimized.scala13
-rw-r--r--src/library/scala/collection/IterableLike.scala46
-rw-r--r--src/library/scala/collection/IterableViewLike.scala12
-rw-r--r--src/library/scala/collection/Iterator.scala7
-rwxr-xr-xsrc/library/scala/collection/LinearSeqOptimized.scala4
-rw-r--r--src/library/scala/collection/SeqViewLike.scala4
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala3
8 files changed, 73 insertions, 18 deletions
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 053a6d211a..fb18ce1d72 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -367,7 +367,7 @@ private[collection] trait GenTraversableOnce[+A] {
def copyToArray[B >: A](xs: Array[B]): Unit
/** Copies values of this $coll to an array.
- * Fills the given array `xs` with values of this $coll, after skipping `start` values.
+ * Fills the given array `xs` with values of this $coll, beginning at index `start`.
* Copying will stop once either the end of the current $coll is reached,
* or the end of the array is reached.
*
diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala
index 04d89299c8..b9a60ae1f1 100755
--- a/src/library/scala/collection/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/IndexedSeqOptimized.scala
@@ -103,11 +103,11 @@ trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self =>
override /*IterableLike*/
def slice(from: Int, until: Int): Repr = {
- val lo = from max 0
- val hi = until min length
- val elems = hi - lo
+ val lo = math.max(from, 0)
+ val hi = math.min(until, length)
+ val elems = math.max(hi - lo, 0)
val b = newBuilder
- b.sizeHint(elems max 0)
+ b.sizeHint(elems)
var i = lo
while (i < hi) {
@@ -185,11 +185,10 @@ trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self =>
override /*SeqLike*/
def segmentLength(p: A => Boolean, from: Int): Int = {
- val start = from
val len = length
- var i = start
+ var i = from
while (i < len && p(this(i))) i += 1
- i - start
+ i - from
}
private def negLength(n: Int) = if (n >= length) -1 else n
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index 458b26207e..b6713b65e4 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -90,9 +90,49 @@ self =>
iterator.next
override /*TraversableLike*/ def slice(from: Int, until: Int): Repr = {
- val lo = from max 0
- if (until <= lo) newBuilder.result
- else newBuilder ++= (iterator drop lo take (until - lo)) result
+ val lo = math.max(from, 0)
+ val elems = until - lo
+ val b = newBuilder
+ if (elems <= 0) b.result
+ else {
+ b.sizeHintBounded(elems, this)
+ var i = 0
+ val it = iterator drop lo
+ while (i < elems && it.hasNext) {
+ b += it.next
+ i += 1
+ }
+ b.result
+ }
+ }
+
+ override /*TraversableLike*/ def take(n: Int): Repr = {
+ val b = newBuilder
+
+ if (n <= 0) b.result
+ else {
+ b.sizeHintBounded(n, this)
+ var i = 0
+ val it = iterator
+ while (i < n && it.hasNext) {
+ b += it.next
+ i += 1
+ }
+ b.result
+ }
+ }
+
+ override /*TraversableLike*/ def drop(n: Int): Repr = {
+ val b = newBuilder
+ val lo = math.max(0, n)
+ b.sizeHint(this, -lo)
+ var i = 0
+ val it = iterator
+ while (i < n && it.hasNext) {
+ it.next
+ i += 1
+ }
+ b ++= it result
}
override /*TraversableLike*/ def takeWhile(p: A => Boolean): Repr = {
diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala
index e0e1329844..e0f1ada2b8 100644
--- a/src/library/scala/collection/IterableViewLike.scala
+++ b/src/library/scala/collection/IterableViewLike.scala
@@ -63,6 +63,8 @@ trait IterableViewLike[+A,
trait ZippedAll[A1 >: A, B] extends Transformed[(A1, B)] with super[GenIterableViewLike].ZippedAll[A1, B]
+ private[this] implicit def asThis(xs: Transformed[A]): This = xs.asInstanceOf[This]
+
/** Boilerplate method, to override in each subclass
* This method could be eliminated if Scala had virtual classes
*/
@@ -81,6 +83,16 @@ trait IterableViewLike[+A,
protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile
protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile
+ // After adding take and drop overrides to IterableLike, these overrides (which do nothing
+ // but duplicate the implementation in TraversableViewLike) had to be added to prevent the
+ // overrides in IterableLike from besting the overrides in TraversableViewLike when mixed
+ // together in e.g. SeqViewLike. This is a suboptimal situation. Examples of failing tests
+ // are run/bug2876 and run/viewtest.
+ protected override def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n))
+ protected override def newDropped(n: Int): Transformed[A] = newSliced(SliceInterval(n, Int.MaxValue))
+ override def drop(n: Int): This = newDropped(n)
+ override def take(n: Int): This = newTaken(n)
+
override def zip[A1 >: A, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[This, (A1, B), That]): That = {
newZipped(that).asInstanceOf[That]
// was: val b = bf(repr)
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 7bd33cbb23..39c1d5b07f 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -975,8 +975,8 @@ trait Iterator[+A] extends TraversableOnce[A] {
}
/** Copies selected values produced by this iterator to an array.
- * Fills the given array `xs` with at most `len` values produced by this
- * iterator, after skipping `start` values.
+ * Fills the given array `xs` starting at index `start` with at most
+ * `len` values produced by this iterator.
* Copying will stop once either the end of the current iterator is reached,
* or the end of the array is reached, or `len` elements have been copied.
*
@@ -987,12 +987,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @param len the maximal number of elements to copy.
* @tparam B the type of the elements of the array.
*
- *
* @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit = {
var i = start
- val end = start + len min xs.length
+ val end = start + math.min(len, xs.length)
while (hasNext && i < end) {
xs(i) = next()
i += 1
diff --git a/src/library/scala/collection/LinearSeqOptimized.scala b/src/library/scala/collection/LinearSeqOptimized.scala
index 7c5cba0665..236a5bdaa3 100755
--- a/src/library/scala/collection/LinearSeqOptimized.scala
+++ b/src/library/scala/collection/LinearSeqOptimized.scala
@@ -168,7 +168,9 @@ trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends Linea
// since we are in collection.*, not immutable.*.
// However making that change will pessimize all the
// immutable linear seqs (like list) which surely expect
- // drop to share.
+ // drop to share. (Or at least it would penalize List if
+ // it didn't override drop. It would be a lot better if
+ // the leaf collections didn't override so many methods.)
//
// Upshot: MutableList is broken and passes part of the
// original list as the result of drop.
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index f79baa7c58..77dc15e695 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -93,6 +93,10 @@ trait SeqViewLike[+A,
} with Patched[B]
protected def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with Prepended[B]
+ // see comment in IterableViewLike.
+ protected override def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n))
+ protected override def newDropped(n: Int): Transformed[A] = newSliced(SliceInterval(n, Int.MaxValue))
+
override def reverse: This = newReversed.asInstanceOf[This]
override def patch[B >: A, That](from: Int, patch: GenSeq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = {
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index dcba9a52a5..99929dd93c 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -43,8 +43,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza
repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]]))
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
- var l = len
- if (repr.length < l) l = repr.length
+ var l = math.min(len, repr.length)
if (xs.length - start < l) l = xs.length - start max 0
Array.copy(repr, 0, xs, start, l)
}