7062169: (coll) micro-optimize ArrayList.remove(Object)
authordl
Sat, 22 Jul 2017 09:03:50 -0700
changeset 45934 59b4dd84cd5d
parent 45933 880c6fdf23e7
child 45935 75c0f4d0ebea
7062169: (coll) micro-optimize ArrayList.remove(Object) Reviewed-by: martin, psandoz, igerasim
jdk/src/java.base/share/classes/java/util/ArrayList.java
--- a/jdk/src/java.base/share/classes/java/util/ArrayList.java	Fri Jul 21 15:01:44 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/ArrayList.java	Sat Jul 22 09:03:50 2017 -0700
@@ -514,15 +514,10 @@
      */
     public E remove(int index) {
         Objects.checkIndex(index, size);
-
-        modCount++;
-        E oldValue = elementData(index);
+        final Object[] es = elementData;
 
-        int numMoved = size - index - 1;
-        if (numMoved > 0)
-            System.arraycopy(elementData, index+1, elementData, index,
-                             numMoved);
-        elementData[--size] = null; // clear to let GC do its work
+        @SuppressWarnings("unchecked") E oldValue = (E) es[index];
+        fastRemove(es, index);
 
         return oldValue;
     }
@@ -541,33 +536,35 @@
      * @return {@code true} if this list contained the specified element
      */
     public boolean remove(Object o) {
-        if (o == null) {
-            for (int index = 0; index < size; index++)
-                if (elementData[index] == null) {
-                    fastRemove(index);
-                    return true;
-                }
-        } else {
-            for (int index = 0; index < size; index++)
-                if (o.equals(elementData[index])) {
-                    fastRemove(index);
-                    return true;
-                }
+        final Object[] es = elementData;
+        final int size = this.size;
+        int i = 0;
+        found: {
+            if (o == null) {
+                for (; i < size; i++)
+                    if (es[i] == null)
+                        break found;
+            } else {
+                for (; i < size; i++)
+                    if (o.equals(es[i]))
+                        break found;
+            }
+            return false;
         }
-        return false;
+        fastRemove(es, i);
+        return true;
     }
 
     /**
      * Private remove method that skips bounds checking and does not
      * return the value removed.
      */
-    private void fastRemove(int index) {
+    private void fastRemove(Object[] es, int i) {
         modCount++;
-        int numMoved = size - index - 1;
-        if (numMoved > 0)
-            System.arraycopy(elementData, index+1, elementData, index,
-                             numMoved);
-        elementData[--size] = null; // clear to let GC do its work
+        final int newSize;
+        if ((newSize = size - 1) > i)
+            System.arraycopy(es, i + 1, es, i, newSize - i);
+        es[size = newSize] = null;
     }
 
     /**
@@ -743,29 +740,30 @@
                         final int from, final int end) {
         Objects.requireNonNull(c);
         final Object[] es = elementData;
-        final boolean modified;
         int r;
         // Optimize for initial run of survivors
-        for (r = from; r < end && c.contains(es[r]) == complement; r++)
-            ;
-        if (modified = (r < end)) {
-            int w = r++;
-            try {
-                for (Object e; r < end; r++)
-                    if (c.contains(e = es[r]) == complement)
-                        es[w++] = e;
-            } catch (Throwable ex) {
-                // Preserve behavioral compatibility with AbstractCollection,
-                // even if c.contains() throws.
-                System.arraycopy(es, r, es, w, end - r);
-                w += end - r;
-                throw ex;
-            } finally {
-                modCount += end - w;
-                shiftTailOverGap(es, w, end);
-            }
+        for (r = from;; r++) {
+            if (r == end)
+                return false;
+            if (c.contains(es[r]) != complement)
+                break;
         }
-        return modified;
+        int w = r++;
+        try {
+            for (Object e; r < end; r++)
+                if (c.contains(e = es[r]) == complement)
+                    es[w++] = e;
+        } catch (Throwable ex) {
+            // Preserve behavioral compatibility with AbstractCollection,
+            // even if c.contains() throws.
+            System.arraycopy(es, r, es, w, end - r);
+            w += end - r;
+            throw ex;
+        } finally {
+            modCount += end - w;
+            shiftTailOverGap(es, w, end);
+        }
+        return true;
     }
 
     /**
@@ -784,7 +782,7 @@
         int expectedModCount = modCount;
         s.defaultWriteObject();
 
-        // Write out size as capacity for behavioural compatibility with clone()
+        // Write out size as capacity for behavioral compatibility with clone()
         s.writeInt(size);
 
         // Write out all elements in the proper order.