summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-11-15 11:14:57 +0000
committerMartin Odersky <odersky@gmail.com>2009-11-15 11:14:57 +0000
commitc43f01c39d029be1a82c78bb2f49da5eb6833ab5 (patch)
tree65b9ac40a15157547ee7959c3a9e29c58825447a /src/library
parent1cd31e2edd031c0d32266de54ef63ddb9233c047 (diff)
downloadscala-c43f01c39d029be1a82c78bb2f49da5eb6833ab5.tar.gz
scala-c43f01c39d029be1a82c78bb2f49da5eb6833ab5.tar.bz2
scala-c43f01c39d029be1a82c78bb2f49da5eb6833ab5.zip
Fixed #2848 and #2630; Improvements in equality...
Fixed #2848 and #2630; Improvements in equality speed
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java82
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala5
2 files changed, 50 insertions, 37 deletions
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index b1cc464513..bd38e37503 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -117,59 +117,71 @@ public class BoxesRunTime
/* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
+ private static int eqTypeCode(Number a) {
+ if ((a instanceof Integer) || (a instanceof Byte)) return INT;
+ if (a instanceof Long) return LONG;
+ if (a instanceof Double) return DOUBLE;
+ if (a instanceof Short) return INT;
+ if (a instanceof Float) return FLOAT;
+ return OTHER;
+ }
+
+ public static boolean equals(Object x, Object y) {
+ if (x == y) return true;
+ if (x == null) return false;
+ return equals2(x, y);
+ }
+
/** Since all applicable logic has to be present in the equals method of a ScalaNumber
* in any case, we dispatch to it as soon as we spot one on either side.
*/
- public static boolean equals(Object x, Object y) {
+ public static boolean equals2(Object x, Object y) {
if (x instanceof Number) {
- if (x instanceof ScalaNumber)
- return x.equals(y);
-
Number xn = (Number)x;
- if (y instanceof Number) {
- if (y instanceof ScalaNumber)
- return y.equals(x);
+ if (y instanceof Number) {
Number yn = (Number)y;
- if ((xn instanceof Double) || (yn instanceof Double))
- return xn.doubleValue() == yn.doubleValue();
- if ((xn instanceof Float) || (yn instanceof Float))
- return xn.floatValue() == yn.floatValue();
- if ((xn instanceof Long) || (yn instanceof Long))
- return xn.longValue() == yn.longValue();
- if (typeCode(x) <= INT && typeCode(y) <= INT)
+ int xcode = eqTypeCode(xn);
+ int ycode = eqTypeCode(yn);
+ switch (ycode > xcode ? ycode : xcode) {
+ case INT:
return xn.intValue() == yn.intValue();
-
- return x.equals(y);
- }
- if (y instanceof Character)
+ case LONG:
+ return xn.longValue() == yn.longValue();
+ case FLOAT:
+ return xn.floatValue() == yn.floatValue();
+ case DOUBLE:
+ return xn.doubleValue() == yn.doubleValue();
+ default:
+ if ((yn instanceof ScalaNumber) && !(xn instanceof ScalaNumber))
+ return y.equals(x);
+ }
+ } else if (y instanceof Character)
return equalsNumChar(xn, (Character)y);
} else if (x instanceof Character) {
Character xc = (Character)x;
if (y instanceof Character)
- return xc.equals(y);
+ return xc.charValue() == ((Character)y).charValue();
if (y instanceof Number)
return equalsNumChar((Number)y, xc);
- } else if (x == null) {
- return y == null;
}
return x.equals(y);
}
- private static boolean equalsNumChar(Number x, Character y) {
- char ch = y.charValue();
- if (x instanceof Double)
- return x.doubleValue() == ch;
- if (x instanceof Float)
- return x.floatValue() == ch;
- if (x instanceof Long)
- return x.longValue() == ch;
- if (x instanceof ScalaNumber)
- return x.equals(y);
- if (typeCode(x) <= INT)
- return x.intValue() == ch;
-
- return x.equals(y);
+ private static boolean equalsNumChar(Number xn, Character yc) {
+ char ch = yc.charValue();
+ switch (eqTypeCode(xn)) {
+ case INT:
+ return xn.intValue() == ch;
+ case LONG:
+ return xn.longValue() == ch;
+ case FLOAT:
+ return xn.floatValue() == ch;
+ case DOUBLE:
+ return xn.doubleValue() == ch;
+ default:
+ return xn.equals(yc);
+ }
}
/** Hashcode algorithm is driven by the requirements imposed
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index a93ff61a41..6467751a1f 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -123,8 +123,9 @@ object ScalaRunTime {
/** Fast path equality method for inlining; used when -optimise is set.
*/
@inline def inlinedEquals(x: Object, y: Object): Boolean =
- if (x eq null) y eq null
- else if (x.isInstanceOf[Number] || x.isInstanceOf[Character]) BoxesRunTime.equals(x, y)
+ if (x eq y) true
+ else if (x eq null) false
+ else if (x.isInstanceOf[Number] || x.isInstanceOf[Character]) BoxesRunTime.equals2(x, y)
else x.equals(y)
def _equals(x: Product, y: Any): Boolean = y match {