diff options
author | Martin Odersky <odersky@gmail.com> | 2009-11-15 11:14:57 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-11-15 11:14:57 +0000 |
commit | c43f01c39d029be1a82c78bb2f49da5eb6833ab5 (patch) | |
tree | 65b9ac40a15157547ee7959c3a9e29c58825447a /src/library | |
parent | 1cd31e2edd031c0d32266de54ef63ddb9233c047 (diff) | |
download | scala-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.java | 82 | ||||
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 5 |
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 { |