diff options
author | Paul Phillips <paulp@improving.org> | 2010-04-23 22:13:41 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-04-23 22:13:41 +0000 |
commit | 6736ca07f22a8da42604a27bda84f71b720b54ed (patch) | |
tree | b4e720c26ad1aab77cefa34ea345e11ebf35291d /src/library | |
parent | eb1ee924dd922db2e967c8a38ec13410eeb7110f (diff) | |
download | scala-6736ca07f22a8da42604a27bda84f71b720b54ed.tar.gz scala-6736ca07f22a8da42604a27bda84f71b720b54ed.tar.bz2 scala-6736ca07f22a8da42604a27bda84f71b720b54ed.zip |
Added size hints to Array.{ iterate, range, tab...
Added size hints to Array.{ iterate, range, tabulate, fill }.
Probably closes #3331, but it would be nice if someone would measure
whether it makes much difference to skip the builder entirely in
those cases where that could be done. No review.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/Array.scala | 5 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/Range.scala | 17 |
2 files changed, 22 insertions, 0 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index f89e8b48a5..c9d929b88c 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -207,6 +207,7 @@ object Array extends FallbackArrayBuilding { */ def fill[T: ClassManifest](n: Int)(elem: => T): Array[T] = { val b = newBuilder[T] + b.sizeHint(n) var i = 0 while (i < n) { b += elem @@ -270,6 +271,7 @@ object Array extends FallbackArrayBuilding { */ def tabulate[T: ClassManifest](n: Int)(f: Int => T): Array[T] = { val b = newBuilder[T] + b.sizeHint(n) var i = 0 while (i < n) { b += f(i) @@ -343,6 +345,8 @@ object Array extends FallbackArrayBuilding { def range(start: Int, end: Int, step: Int): Array[Int] = { if (step == 0) throw new IllegalArgumentException("zero step") val b = newBuilder[Int] + b.sizeHint(Range.count(start, end, step, false)) + var i = start while (if (step < 0) end < i else i < end) { b += i @@ -360,6 +364,7 @@ object Array extends FallbackArrayBuilding { */ def iterate[T: ClassManifest](start: T, len: Int)(f: T => T): Array[T] = { val b = newBuilder[T] + b.sizeHint(len) var acc = start var i = 0 while (i < len) { diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 8f1f7d58a6..0f20b1ea04 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -219,6 +219,23 @@ class Range(val start: Int, val end: Int, val step: Int) extends IndexedSeq[Int] object Range { private[immutable] val MAX_PRINT = 512 // some arbitrary value + /** Calculates the number of elements in a range given start, end, step, and + * whether or not it is inclusive. Returns -1 if parameters are invalid. + */ + def count(start: Int, end: Int, step: Int): Int = count(start, end, step, false) + def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = { + def last = + if (isInclusive && step < 0) end - 1 + else if (isInclusive && step > 0) end + 1 + else end + + if (step == 0) -1 + else if (start == end) { if (isInclusive) 1 else 0 } + else if (end > start != step > 0) -1 + else if (step == 1 || step == -1) last - start + else ((last - start - 1) / step) + 1 + } + class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { override def isInclusive = true override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) |