summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-23 22:13:41 +0000
committerPaul Phillips <paulp@improving.org>2010-04-23 22:13:41 +0000
commit6736ca07f22a8da42604a27bda84f71b720b54ed (patch)
treeb4e720c26ad1aab77cefa34ea345e11ebf35291d /src/library
parenteb1ee924dd922db2e967c8a38ec13410eeb7110f (diff)
downloadscala-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.scala5
-rw-r--r--src/library/scala/collection/immutable/Range.scala17
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)