summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Ochsenreither <simon@ochsenreither.de>2013-05-23 21:04:00 +0200
committerSimon Ochsenreither <simon@ochsenreither.de>2013-06-23 18:18:51 +0200
commit4cbb6a93b9d46174cd86d6c9b6ecaeba3ba67e9d (patch)
tree80032e4f62d92439ce8a8b78470658c984198647 /src
parentb6bc53479984f9fc0528a8ce3f6f0b582cb4147f (diff)
downloadscala-4cbb6a93b9d46174cd86d6c9b6ecaeba3ba67e9d.tar.gz
scala-4cbb6a93b9d46174cd86d6c9b6ecaeba3ba67e9d.tar.bz2
scala-4cbb6a93b9d46174cd86d6c9b6ecaeba3ba67e9d.zip
SI-7511 Remove indirection of numeric methods
Methods on `Rich<AnyVal>`s like `abs`, `doubleValue`, `floatValue`, `longValue`, `intValue`, `byteValue`, `shortValue`, `min`, `max`, `signum` are slow because they go through multiple indirections including typeclasses and boxing. For instance, take `1L.abs`: Instead of just computing and returning the result (like it is done in `RichInt`), this is what happens: - `RichLong` inherits `abs` by extending `ScalaNumberProxy[T]` - `ScalaNumberProxy[T]` has an abstract `protected implicit def num: Numeric[T]` - This method is implemented in `RichLong` and points to `scala.math.Numeric.LongIsIntegral` - The actual method `abs` now calls `num.abs(self)`
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/math/ScalaNumericConversions.scala1
-rw-r--r--src/library/scala/runtime/RichByte.scala14
-rw-r--r--src/library/scala/runtime/RichChar.scala14
-rw-r--r--src/library/scala/runtime/RichDouble.scala47
-rw-r--r--src/library/scala/runtime/RichFloat.scala47
-rw-r--r--src/library/scala/runtime/RichInt.scala47
-rw-r--r--src/library/scala/runtime/RichLong.scala27
-rw-r--r--src/library/scala/runtime/RichShort.scala14
-rw-r--r--src/library/scala/runtime/ScalaNumberProxy.scala4
9 files changed, 147 insertions, 68 deletions
diff --git a/src/library/scala/math/ScalaNumericConversions.scala b/src/library/scala/math/ScalaNumericConversions.scala
index 336991781e..0006133b13 100644
--- a/src/library/scala/math/ScalaNumericConversions.scala
+++ b/src/library/scala/math/ScalaNumericConversions.scala
@@ -20,6 +20,7 @@ trait ScalaNumericConversions extends ScalaNumber with ScalaNumericAnyConversion
* across all the numeric types, suitable for use in value classes.
*/
trait ScalaNumericAnyConversions extends Any {
+ /** @return `'''true'''` if this number has no decimal component, `'''false'''` otherwise. */
def isWhole(): Boolean
def underlying(): Any
diff --git a/src/library/scala/runtime/RichByte.scala b/src/library/scala/runtime/RichByte.scala
index ea23cb8867..ce658d2277 100644
--- a/src/library/scala/runtime/RichByte.scala
+++ b/src/library/scala/runtime/RichByte.scala
@@ -13,4 +13,18 @@ package runtime
final class RichByte(val self: Byte) extends AnyVal with ScalaWholeNumberProxy[Byte] {
protected def num = scala.math.Numeric.ByteIsIntegral
protected def ord = scala.math.Ordering.Byte
+
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self.toFloat
+ override def longValue() = self.toLong
+ override def intValue() = self.toInt
+ override def byteValue() = self
+ override def shortValue() = self.toShort
+
+ override def isValidByte = true
+
+ override def abs: Byte = math.abs(self).toByte
+ override def max(that: Byte): Byte = math.max(self, that).toByte
+ override def min(that: Byte): Byte = math.min(self, that).toByte
+ override def signum: Int = math.signum(self.toInt)
}
diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala
index c069fd1fef..71ea3a21e1 100644
--- a/src/library/scala/runtime/RichChar.scala
+++ b/src/library/scala/runtime/RichChar.scala
@@ -16,6 +16,20 @@ final class RichChar(val self: Char) extends AnyVal with IntegralProxy[Char] {
protected def num = scala.math.Numeric.CharIsIntegral
protected def ord = scala.math.Ordering.Char
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self.toFloat
+ override def longValue() = self.toLong
+ override def intValue() = self.toInt
+ override def byteValue() = self.toByte
+ override def shortValue() = self.toShort
+
+ override def isValidChar = true
+
+ override def abs: Char = self
+ override def max(that: Char): Char = math.max(self.toInt, that.toInt).toChar
+ override def min(that: Char): Char = math.min(self.toInt, that.toInt).toChar
+ override def signum: Int = math.signum(self.toInt)
+
def asDigit: Int = Character.digit(self, Character.MAX_RADIX)
def isControl: Boolean = Character.isISOControl(self)
diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala
index 2f16a296b3..9d7a55d5cd 100644
--- a/src/library/scala/runtime/RichDouble.scala
+++ b/src/library/scala/runtime/RichDouble.scala
@@ -14,6 +14,35 @@ final class RichDouble(val self: Double) extends AnyVal with FractionalProxy[Dou
protected def ord = scala.math.Ordering.Double
protected def integralNum = scala.math.Numeric.DoubleAsIfIntegral
+ override def doubleValue() = self
+ override def floatValue() = self.toFloat
+ override def longValue() = self.toLong
+ override def intValue() = self.toInt
+ override def byteValue() = self.toByte
+ override def shortValue() = self.toShort
+
+ override def isWhole = {
+ val l = self.toLong
+ l.toDouble == self || l == Long.MaxValue && self < Double.PositiveInfinity || l == Long.MinValue && self > Double.NegativeInfinity
+ }
+ override def isValidByte = self.toByte.toDouble == self
+ override def isValidShort = self.toShort.toDouble == self
+ override def isValidChar = self.toChar.toDouble == self
+ override def isValidInt = self.toInt.toDouble == self
+ // override def isValidLong = { val l = self.toLong; l.toDouble == self && l != Long.MaxValue }
+ // override def isValidFloat = self.toFloat.toDouble == self
+ // override def isValidDouble = !java.lang.Double.isNaN(self)
+
+ def isNaN: Boolean = java.lang.Double.isNaN(self)
+ def isInfinity: Boolean = java.lang.Double.isInfinite(self)
+ def isPosInfinity: Boolean = Double.PositiveInfinity == self
+ def isNegInfinity: Boolean = Double.NegativeInfinity == self
+
+ override def abs: Double = math.abs(self)
+ override def max(that: Double): Double = math.max(self, that)
+ override def min(that: Double): Double = math.min(self, that)
+ override def signum: Int = math.signum(self).toInt // !!! NaN
+
def round: Long = math.round(self)
def ceil: Double = math.ceil(self)
def floor: Double = math.floor(self)
@@ -30,22 +59,4 @@ final class RichDouble(val self: Double) extends AnyVal with FractionalProxy[Dou
* @return the measurement of the angle x in degrees.
*/
def toDegrees: Double = math.toDegrees(self)
-
- // isNaN is provided by the implicit conversion to java.lang.Double
- // def isNaN: Boolean = java.lang.Double.isNaN(self)
- def isInfinity: Boolean = java.lang.Double.isInfinite(self)
- def isPosInfinity: Boolean = isInfinity && self > 0.0
- def isNegInfinity: Boolean = isInfinity && self < 0.0
-
- override def isValidByte = self.toByte.toDouble == self
- override def isValidShort = self.toShort.toDouble == self
- override def isValidChar = self.toChar.toDouble == self
- override def isValidInt = self.toInt.toDouble == self
- // override def isValidLong = { val l = self.toLong; l.toDouble == self && l != Long.MaxValue }
- // override def isValidFloat = self.toFloat.toDouble == self
- // override def isValidDouble = !java.lang.Double.isNaN(self)
- override def isWhole = {
- val l = self.toLong
- l.toDouble == self || l == Long.MaxValue && self < Double.PositiveInfinity || l == Long.MinValue && self > Double.NegativeInfinity
- }
}
diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala
index 0bca033b7b..93777f2405 100644
--- a/src/library/scala/runtime/RichFloat.scala
+++ b/src/library/scala/runtime/RichFloat.scala
@@ -14,6 +14,35 @@ final class RichFloat(val self: Float) extends AnyVal with FractionalProxy[Float
protected def ord = scala.math.Ordering.Float
protected def integralNum = scala.math.Numeric.FloatAsIfIntegral
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self
+ override def longValue() = self.toLong
+ override def intValue() = self.toInt
+ override def byteValue() = self.toByte
+ override def shortValue() = self.toShort
+
+ override def isWhole = {
+ val l = self.toLong
+ l.toFloat == self || l == Long.MaxValue && self < Float.PositiveInfinity || l == Long.MinValue && self > Float.NegativeInfinity
+ }
+ override def isValidByte = self.toByte.toFloat == self
+ override def isValidShort = self.toShort.toFloat == self
+ override def isValidChar = self.toChar.toFloat == self
+ override def isValidInt = { val i = self.toInt; i.toFloat == self && i != Int.MaxValue }
+ // override def isValidLong = { val l = self.toLong; l.toFloat == self && l != Long.MaxValue }
+ // override def isValidFloat = !java.lang.Float.isNaN(self)
+ // override def isValidDouble = !java.lang.Float.isNaN(self)
+
+ def isNaN: Boolean = java.lang.Float.isNaN(self)
+ def isInfinity: Boolean = java.lang.Float.isInfinite(self)
+ def isPosInfinity: Boolean = Float.PositiveInfinity == self
+ def isNegInfinity: Boolean = Float.NegativeInfinity == self
+
+ override def abs: Float = math.abs(self)
+ override def max(that: Float): Float = math.max(self, that)
+ override def min(that: Float): Float = math.min(self, that)
+ override def signum: Int = math.signum(self).toInt // !!! NaN
+
def round: Int = math.round(self)
def ceil: Float = math.ceil(self.toDouble).toFloat
def floor: Float = math.floor(self.toDouble).toFloat
@@ -31,22 +60,4 @@ final class RichFloat(val self: Float) extends AnyVal with FractionalProxy[Float
* @return the measurement of the angle `x` in degrees.
*/
def toDegrees: Float = math.toDegrees(self.toDouble).toFloat
-
- // isNaN is provided by the implicit conversion to java.lang.Float
- // def isNaN: Boolean = java.lang.Float.isNaN(self)
- def isInfinity: Boolean = java.lang.Float.isInfinite(self)
- def isPosInfinity: Boolean = isInfinity && self > 0.0f
- def isNegInfinity: Boolean = isInfinity && self < 0.0f
-
- override def isValidByte = self.toByte.toFloat == self
- override def isValidShort = self.toShort.toFloat == self
- override def isValidChar = self.toChar.toFloat == self
- override def isValidInt = { val i = self.toInt; i.toFloat == self && i != Int.MaxValue }
- // override def isValidLong = { val l = self.toLong; l.toFloat == self && l != Long.MaxValue }
- // override def isValidFloat = !java.lang.Float.isNaN(self)
- // override def isValidDouble = !java.lang.Float.isNaN(self)
- override def isWhole = {
- val l = self.toLong
- l.toFloat == self || l == Long.MaxValue && self < Float.PositiveInfinity || l == Long.MinValue && self > Float.NegativeInfinity
- }
}
diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala
index a39710b146..cc4e92dfa3 100644
--- a/src/library/scala/runtime/RichInt.scala
+++ b/src/library/scala/runtime/RichInt.scala
@@ -9,7 +9,6 @@
package scala
package runtime
-
import scala.collection.immutable.Range
// Note that this does not implement IntegralProxy[Int] so that it can return
@@ -17,14 +16,33 @@ import scala.collection.immutable.Range
final class RichInt(val self: Int) extends AnyVal with ScalaNumberProxy[Int] with RangedProxy[Int] {
protected def num = scala.math.Numeric.IntIsIntegral
protected def ord = scala.math.Ordering.Int
- type ResultWithoutStep = Range
- /**
- * @return `'''true'''` if this number has no decimal component.
- * Always returns `'''true'''` for `RichInt`.
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self.toFloat
+ override def longValue() = self.toLong
+ override def intValue() = self
+ override def byteValue() = self.toByte
+ override def shortValue() = self.toShort
+
+ /** Returns `'''true'''` if this number has no decimal component.
+ * Always `'''true'''` for `RichInt`.
*/
def isWhole() = true
+ override def isValidInt = true
+ def isValidLong = true
+
+ override def abs: Int = math.abs(self)
+ override def max(that: Int): Int = math.max(self, that)
+ override def min(that: Int): Int = math.min(self, that)
+ override def signum: Int = math.signum(self)
+
+ def toBinaryString: String = java.lang.Integer.toBinaryString(self)
+ def toHexString: String = java.lang.Integer.toHexString(self)
+ def toOctalString: String = java.lang.Integer.toOctalString(self)
+
+ type ResultWithoutStep = Range
+
/**
* @param end The final bound of the range to make.
* @return A [[scala.collection.immutable.Range]] from `this` up to but
@@ -55,23 +73,4 @@ final class RichInt(val self: Int) extends AnyVal with ScalaNumberProxy[Int] wit
* and including `end`.
*/
def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step)
-
- /**
- * @return `'''this'''` if `'''this''' < that` or `that` otherwise
- */
- override def min(that: Int): Int = if (self < that) self else that
-
- /**
- * @return `'''this'''` if `'''this''' > that` or `that` otherwise
- */
- override def max(that: Int): Int = if (self > that) self else that
-
- /**
- * Computes the absolute value of `'''this'''`.
- */
- override def abs: Int = if (self < 0) -self else self
-
- def toBinaryString: String = java.lang.Integer.toBinaryString(self)
- def toHexString: String = java.lang.Integer.toHexString(self)
- def toOctalString: String = java.lang.Integer.toOctalString(self)
}
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
index e5b39b1c09..df0bbec047 100644
--- a/src/library/scala/runtime/RichLong.scala
+++ b/src/library/scala/runtime/RichLong.scala
@@ -9,20 +9,31 @@
package scala
package runtime
-
final class RichLong(val self: Long) extends AnyVal with IntegralProxy[Long] {
protected def num = scala.math.Numeric.LongIsIntegral
protected def ord = scala.math.Ordering.Long
- def toBinaryString: String = java.lang.Long.toBinaryString(self)
- def toHexString: String = java.lang.Long.toHexString(self)
- def toOctalString: String = java.lang.Long.toOctalString(self)
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self.toFloat
+ override def longValue() = self
+ override def intValue() = self.toInt
+ override def byteValue() = self.toByte
+ override def shortValue() = self.toShort
- override def isValidByte = self.toByte.toLong == self
+ override def isValidByte = self.toByte.toLong == self
override def isValidShort = self.toShort.toLong == self
- override def isValidChar = self.toChar.toLong == self
- override def isValidInt = self.toInt.toLong == self
- // override def isValidLong = true
+ override def isValidChar = self.toChar.toLong == self
+ override def isValidInt = self.toInt.toLong == self
+ def isValidLong = true
// override def isValidFloat = self.toFloat.toLong == self && self != Long.MaxValue
// override def isValidDouble = self.toDouble.toLong == self && self != Long.MaxValue
+
+ override def abs: Long = math.abs(self)
+ override def max(that: Long): Long = math.max(self, that)
+ override def min(that: Long): Long = math.min(self, that)
+ override def signum: Int = math.signum(self).toInt
+
+ def toBinaryString: String = java.lang.Long.toBinaryString(self)
+ def toHexString: String = java.lang.Long.toHexString(self)
+ def toOctalString: String = java.lang.Long.toOctalString(self)
}
diff --git a/src/library/scala/runtime/RichShort.scala b/src/library/scala/runtime/RichShort.scala
index 3e5d8781ff..b35beff7eb 100644
--- a/src/library/scala/runtime/RichShort.scala
+++ b/src/library/scala/runtime/RichShort.scala
@@ -13,4 +13,18 @@ package runtime
final class RichShort(val self: Short) extends AnyVal with ScalaWholeNumberProxy[Short] {
protected def num = scala.math.Numeric.ShortIsIntegral
protected def ord = scala.math.Ordering.Short
+
+ override def doubleValue() = self.toDouble
+ override def floatValue() = self.toFloat
+ override def longValue() = self.toLong
+ override def intValue() = self.toInt
+ override def byteValue() = self.toByte
+ override def shortValue() = self
+
+ override def isValidShort = true
+
+ override def abs: Short = math.abs(self.toInt).toShort
+ override def max(that: Short): Short = math.max(self.toInt, that.toInt).toShort
+ override def min(that: Short): Short = math.min(self.toInt, that.toInt).toShort
+ override def signum: Int = math.signum(self.toInt)
}
diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala
index 6ea6448b1a..5e4da24c0d 100644
--- a/src/library/scala/runtime/ScalaNumberProxy.scala
+++ b/src/library/scala/runtime/ScalaNumberProxy.scala
@@ -32,9 +32,13 @@ trait ScalaNumberProxy[T] extends Any with ScalaNumericAnyConversions with Typed
def byteValue() = intValue().toByte
def shortValue() = intValue().toShort
+ /** Returns `'''this'''` if `'''this''' < that` or `that` otherwise. */
def min(that: T): T = num.min(self, that)
+ /** Returns `'''this'''` if `'''this''' > that` or `that` otherwise. */
def max(that: T): T = num.max(self, that)
+ /** Returns the absolute value of `'''this'''`. */
def abs = num.abs(self)
+ /** Returns the signum of `'''this'''`. */
def signum = num.signum(self)
}
trait ScalaWholeNumberProxy[T] extends Any with ScalaNumberProxy[T] {