summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-05-21 17:46:14 +0000
committerPaul Phillips <paulp@improving.org>2011-05-21 17:46:14 +0000
commit86e7c9b205f28f6fb01199bcb514bfc0e3062e86 (patch)
treee0e12e07007622d54bcb5460dda42a4f996cbc28 /src
parent9d2c066436453b78b977d44a6eb4da446aca87b2 (diff)
downloadscala-86e7c9b205f28f6fb01199bcb514bfc0e3062e86.tar.gz
scala-86e7c9b205f28f6fb01199bcb514bfc0e3062e86.tar.bz2
scala-86e7c9b205f28f6fb01199bcb514bfc0e3062e86.zip
Making Range creation less slow, no review.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/immutable/NumericRange.scala18
-rw-r--r--src/library/scala/collection/immutable/Range.scala9
2 files changed, 15 insertions, 12 deletions
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala
index e4b539f962..0e32118696 100644
--- a/src/library/scala/collection/immutable/NumericRange.scala
+++ b/src/library/scala/collection/immutable/NumericRange.scala
@@ -192,24 +192,22 @@ extends IndexedSeq[T] with Serializable {
/** A companion object for numeric ranges.
*/
object NumericRange {
- import Ordering.Implicits._
- import math.Integral.Implicits._
-
/** Calculates the number of elements in a range given start, end, step, and
* whether or not it is inclusive. Throws an exception if step == 0 or
* the number of elements exceeds the maximum Int.
*/
- def count[T: Integral](start: T, end: T, step: T, isInclusive: Boolean): Int = {
- val zero = implicitly[Integral[T]].zero
- val upward = start < end
- val posStep = step > zero
+ def count[T](start: T, end: T, step: T, isInclusive: Boolean)(implicit num: Integral[T]): Int = {
+ val zero = num.zero
+ val upward = num.lt(start, end)
+ val posStep = num.gt(step, zero)
if (step == zero) throw new IllegalArgumentException("step cannot be 0.")
else if (start == end) if (isInclusive) 1 else 0
else if (upward != posStep) 0
else {
- val jumps = ((end - start) / step).toLong
- val remainder = ((end - start) % step).toLong
+ val diff = num.minus(end, start)
+ val jumps = num.toLong(num.quot(diff, step))
+ val remainder = num.toLong(num.rem(diff, step))
val longCount = jumps + (
if (!isInclusive && zero == remainder) 0 else 1
)
@@ -220,7 +218,7 @@ object NumericRange {
* overflow turn up as an empty range.
*/
// The second condition contradicts an empty result.
- val isOverflow = longCount == 0 && (start + step < end) == upward
+ val isOverflow = longCount == 0 && num.lt(num.plus(start, step), end) == upward
if (longCount > scala.Int.MaxValue || longCount < 0L || isOverflow) {
val word = if (isInclusive) "to" else "until"
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index b22998fb4b..ed4f4615c2 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -243,8 +243,13 @@ object Range {
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 =
- NumericRange.count[Long](start, end, step, isInclusive)
+ def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = {
+ // faster path for the common counting range
+ if (start >= 0 && end > start && end < scala.Int.MaxValue && step == 1)
+ (end - start) + ( if (isInclusive) 1 else 0 )
+ else
+ NumericRange.count[Long](start, end, step, isInclusive)
+ }
class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) {
// override def par = new ParRange(this)