Attached is a patch that improves the performance of an Float/Double compare by exploiting information carried in their bit integer/long versions sign bit. It removes one comparison from the normal path, as well as making other compares with ints/longs. When sorting an array of floats this can yield a little under a 8% speed up on a Pentium 4. There's a thread discussing whether this is a good or bad idea on the main mailing list, but so far I'm merrily talking to myself :-)

Ian
--- java/lang/Double.java       2006-12-10 20:25:44.000000000 +0000
+++ java/lang/Double.java       2007-06-30 22:21:39.986100000 +0100
@@ -587,16 +587,17 @@
    */
   public static int compare(double x, double y)
   {
-    if (isNaN(x))
-      return isNaN(y) ? 0 : 1;
-    if (isNaN(y))
-      return -1;
-    // recall that 0.0 == -0.0, so we convert to infinites and try again
-    if (x == 0 && y == 0)
-      return (int) (1 / x - 1 / y);
-    if (x == y)
-      return 0;
-
-    return x > y ? 1 : -1;
+    long lx = doubleToLongBits(x);
+    long ly = doubleToLongBits(y);
+    if (lx == ly) return 0;
+    if (isNaN(x)) return 1;
+    if (isNaN(y)) return -1;
+    int lx_sign = (int)(lx>>63);
+    int ly_sign = (int)(ly>>63);
+    if (lx_sign == ly_sign) {
+      return x > y ? 1 : -1;
+    } else {
+      return lx_sign - ly_sign;
+    }
   }
 }
--- java/lang/Float.java        2006-12-10 20:25:44.000000000 +0000
+++ java/lang/Float.java        2007-06-30 22:10:46.099648000 +0100
@@ -596,16 +596,17 @@
    */
   public static int compare(float x, float y)
   {
-    if (isNaN(x))
-      return isNaN(y) ? 0 : 1;
-    if (isNaN(y))
-      return -1;
-    // recall that 0.0 == -0.0, so we convert to infinities and try again
-    if (x == 0 && y == 0)
-      return (int) (1 / x - 1 / y);
-    if (x == y)
-      return 0;
-
-    return x > y ? 1 : -1;
+    int ix = floatToIntBits(x);
+    int iy = floatToIntBits(y);
+    if (ix == iy) return 0;
+    if (isNaN(x)) return 1;
+    if (isNaN(y)) return -1;
+    int ix_sign = ix>>31;
+    int iy_sign = iy>>31;
+    if (ix_sign == iy_sign) {
+      return x > y ? 1 : -1;
+    } else {
+      return ix_sign - iy_sign;
+    }
   }
 }

Reply via email to