8205194: Improve the Array Comparison when there is mismatch at first element.
authorvdeshpande
Fri, 22 Jun 2018 12:51:49 -0700
changeset 50726 d7cf64ce3950
parent 50725 d5c59fab1bdb
child 50727 081b132c4dc0
8205194: Improve the Array Comparison when there is mismatch at first element. Summary: perform the first element comparison before the call to vectorizedMismatch method Reviewed-by: psandoz, rriggs, igerasim
src/java.base/share/classes/java/nio/BufferMismatch.java
src/java.base/share/classes/jdk/internal/util/ArraysSupport.java
--- a/src/java.base/share/classes/java/nio/BufferMismatch.java	Fri Jun 22 12:05:36 2018 -0700
+++ b/src/java.base/share/classes/java/nio/BufferMismatch.java	Fri Jun 22 12:51:49 2018 -0700
@@ -34,6 +34,8 @@
     static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 7) {
+            if (a.get(aOff) != b.get(bOff))
+                return 0;
             i = ArraysSupport.vectorizedMismatch(
                     a.base(), a.address + aOff,
                     b.base(), b.address + bOff,
@@ -56,6 +58,8 @@
         // (order is null) then the slow path is taken
         if (length > 3 && a.charRegionOrder() == b.charRegionOrder()
             && a.charRegionOrder() != null && b.charRegionOrder() != null) {
+            if (a.get(aOff) != b.get(bOff))
+                return 0;
             i = ArraysSupport.vectorizedMismatch(
                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
@@ -74,6 +78,8 @@
     static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 3 && a.order() == b.order()) {
+            if (a.get(aOff) != b.get(bOff))
+                return 0;
             i = ArraysSupport.vectorizedMismatch(
                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
@@ -92,6 +98,8 @@
     static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 1 && a.order() == b.order()) {
+            if (a.get(aOff) != b.get(bOff))
+                return 0;
             i = ArraysSupport.vectorizedMismatch(
                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
@@ -110,11 +118,13 @@
     static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 1 && a.order() == b.order()) {
-            i = ArraysSupport.vectorizedMismatch(
-                    a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
-                    b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
-                    length,
-                    ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
+            if (Float.floatToRawIntBits(a.get(aOff)) == Float.floatToRawIntBits(b.get(bOff))) {
+                i = ArraysSupport.vectorizedMismatch(
+                        a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
+                        b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
+                        length,
+                        ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
+            }
             // Mismatched
             if (i >= 0) {
                 // Check if mismatch is not associated with two NaN values; and
@@ -146,6 +156,8 @@
     static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 0 && a.order() == b.order()) {
+            if (a.get(aOff) != b.get(bOff))
+                return 0;
             i = ArraysSupport.vectorizedMismatch(
                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
@@ -163,11 +175,13 @@
     static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {
         int i = 0;
         if (length > 0 && a.order() == b.order()) {
-            i = ArraysSupport.vectorizedMismatch(
-                    a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
-                    b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
-                    length,
-                    ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+            if (Double.doubleToRawLongBits(a.get(aOff)) == Double.doubleToRawLongBits(b.get(bOff))) {
+                i = ArraysSupport.vectorizedMismatch(
+                        a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
+                        b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
+                        length,
+                        ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+            }
             // Mismatched
             if (i >= 0) {
                 // Check if mismatch is not associated with two NaN values; and
--- a/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java	Fri Jun 22 12:05:36 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java	Fri Jun 22 12:51:49 2018 -0700
@@ -166,6 +166,8 @@
                                int length) {
         int i = 0;
         if (length > 7) {
+            if (a[0] != b[0])
+                return 0;
             i = vectorizedMismatch(
                     a, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
                     b, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
@@ -186,6 +188,8 @@
                                int length) {
         int i = 0;
         if (length > 7) {
+            if (a[aFromIndex] != b[bFromIndex])
+                return 0;
             int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex;
             int bOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + bFromIndex;
             i = vectorizedMismatch(
@@ -228,6 +232,8 @@
 
         int i = 0;
         if (length > 7) {
+            if (a[0] != b[0])
+                return 0;
             i = vectorizedMismatch(
                     a, Unsafe.ARRAY_BYTE_BASE_OFFSET,
                     b, Unsafe.ARRAY_BYTE_BASE_OFFSET,
@@ -275,6 +281,8 @@
 
         int i = 0;
         if (length > 7) {
+            if (a[aFromIndex] != b[bFromIndex])
+                return 0;
             int aOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + aFromIndex;
             int bOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + bFromIndex;
             i = vectorizedMismatch(
@@ -300,6 +308,8 @@
                                int length) {
         int i = 0;
         if (length > 3) {
+            if (a[0] != b[0])
+                return 0;
             i = vectorizedMismatch(
                     a, Unsafe.ARRAY_CHAR_BASE_OFFSET,
                     b, Unsafe.ARRAY_CHAR_BASE_OFFSET,
@@ -320,6 +330,8 @@
                                int length) {
         int i = 0;
         if (length > 3) {
+            if (a[aFromIndex] != b[bFromIndex])
+                return 0;
             int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
             int bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
             i = vectorizedMismatch(
@@ -345,6 +357,8 @@
                                int length) {
         int i = 0;
         if (length > 3) {
+            if (a[0] != b[0])
+                return 0;
             i = vectorizedMismatch(
                     a, Unsafe.ARRAY_SHORT_BASE_OFFSET,
                     b, Unsafe.ARRAY_SHORT_BASE_OFFSET,
@@ -365,6 +379,8 @@
                                int length) {
         int i = 0;
         if (length > 3) {
+            if (a[aFromIndex] != b[bFromIndex])
+                return 0;
             int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
             int bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
             i = vectorizedMismatch(
@@ -390,6 +406,8 @@
                                int length) {
         int i = 0;
         if (length > 1) {
+            if (a[0] != b[0])
+                return 0;
             i = vectorizedMismatch(
                     a, Unsafe.ARRAY_INT_BASE_OFFSET,
                     b, Unsafe.ARRAY_INT_BASE_OFFSET,
@@ -410,6 +428,8 @@
                                int length) {
         int i = 0;
         if (length > 1) {
+            if (a[aFromIndex] != b[bFromIndex])
+                return 0;
             int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
             int bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
             i = vectorizedMismatch(
@@ -441,12 +461,14 @@
                                int length) {
         int i = 0;
         if (length > 1) {
-            int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
-            int bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
-            i = vectorizedMismatch(
-                    a, aOffset,
-                    b, bOffset,
-                    length, LOG2_ARRAY_FLOAT_INDEX_SCALE);
+            if (Float.floatToRawIntBits(a[aFromIndex]) == Float.floatToRawIntBits(b[bFromIndex])) {
+                int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
+                int bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
+                i = vectorizedMismatch(
+                        a, aOffset,
+                        b, bOffset,
+                        length, LOG2_ARRAY_FLOAT_INDEX_SCALE);
+            }
             // Mismatched
             if (i >= 0) {
                 // Check if mismatch is not associated with two NaN values
@@ -481,6 +503,8 @@
         if (length == 0) {
             return -1;
         }
+        if (a[0] != b[0])
+            return 0;
         int i = vectorizedMismatch(
                 a, Unsafe.ARRAY_LONG_BASE_OFFSET,
                 b, Unsafe.ARRAY_LONG_BASE_OFFSET,
@@ -494,6 +518,8 @@
         if (length == 0) {
             return -1;
         }
+        if (a[aFromIndex] != b[bFromIndex])
+            return 0;
         int aOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
         int bOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
         int i = vectorizedMismatch(
@@ -518,12 +544,15 @@
         if (length == 0) {
             return -1;
         }
-        int aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
-        int bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
-        int i = vectorizedMismatch(
-                a, aOffset,
-                b, bOffset,
-                length, LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+        int i = 0;
+        if (Double.doubleToRawLongBits(a[aFromIndex]) == Double.doubleToRawLongBits(b[bFromIndex])) {
+            int aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+            int bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+            i = vectorizedMismatch(
+                    a, aOffset,
+                    b, bOffset,
+                    length, LOG2_ARRAY_DOUBLE_INDEX_SCALE);
+        }
         if (i >= 0) {
             // Check if mismatch is not associated with two NaN values
             if (!Double.isNaN(a[aFromIndex + i]) || !Double.isNaN(b[bFromIndex + i]))