test/jdk/java/util/Collection/IteratorMicroBenchmark.java
changeset 53781 940046624bf8
parent 50764 5637aca18f1d
--- a/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Fri Feb 15 11:18:01 2019 -0800
+++ b/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Fri Feb 15 11:18:01 2019 -0800
@@ -69,8 +69,6 @@
  * Be patient; this program runs for a very long time.
  * For faster runs, restrict execution using command line args.
  *
- * This is an interface based version of ArrayList/IteratorMicroBenchmark
- *
  * @author Martin Buchholz
  */
 public class IteratorMicroBenchmark {
@@ -115,7 +113,9 @@
         CountDownLatch finalized = new CountDownLatch(1);
         ReferenceQueue<Object> queue = new ReferenceQueue<>();
         WeakReference<Object> ref = new WeakReference<>(
-            new Object() { protected void finalize() { finalized.countDown(); }},
+            new Object() {
+                @SuppressWarnings("deprecation")
+                protected void finalize() { finalized.countDown(); }},
             queue);
         try {
             for (int tries = 3; tries--> 0; ) {
@@ -267,16 +267,22 @@
             });
     }
 
-    static List<Integer> makeSubList(List<Integer> list) {
+    String goodClassName(Object x) {
+        return goodClassName(x.getClass());
+    }
+
+    static List<Integer> makeSubList(
+        List<Integer> elements,
+        UnaryOperator<List<Integer>> copyConstructor) {
+        final ArrayList<Integer> padded = new ArrayList<>();
         final ThreadLocalRandom rnd = ThreadLocalRandom.current();
-        int size = list.size();
-        if (size <= 2) return list.subList(0, size);
-        List<Integer> subList = list.subList(rnd.nextInt(0, 2),
-                                             size - rnd.nextInt(0, 2));
-        List<Integer> copy = new ArrayList<>(list);
-        subList.clear();
-        subList.addAll(copy);
-        return subList;
+        final int frontPorch = rnd.nextInt(3);
+        final int backPorch = rnd.nextInt(3);
+        for (int n = frontPorch; n--> 0; ) padded.add(rnd.nextInt());
+        padded.addAll(elements);
+        for (int n = backPorch; n--> 0; ) padded.add(rnd.nextInt());
+        return copyConstructor.apply(padded)
+            .subList(frontPorch, frontPorch + elements.size());
     }
 
     void run() throws Throwable {
@@ -297,22 +303,42 @@
             abq.add(abq.remove());
         }
 
-        ArrayList<Job> jobs = Stream.<Collection<Integer>>of(
-                al, ad, abq,
-                makeSubList(new ArrayList<>(al)),
+        final Integer[] array = al.toArray(new Integer[0]);
+        final List<Integer> immutableSubList
+            = makeSubList(al, x -> List.of(x.toArray(new Integer[0])));
+
+        Stream<Collection<Integer>> collections = concatStreams(
+            Stream.of(
+                // Lists and their subLists
+                al,
+                makeSubList(al, ArrayList::new),
+                new Vector<>(al),
+                makeSubList(al, Vector::new),
                 new LinkedList<>(al),
-                makeSubList(new LinkedList<>(al)),
+                makeSubList(al, LinkedList::new),
+                new CopyOnWriteArrayList<>(al),
+                makeSubList(al, CopyOnWriteArrayList::new),
+
+                ad,
                 new PriorityQueue<>(al),
-                new Vector<>(al),
-                makeSubList(new Vector<>(al)),
-                new CopyOnWriteArrayList<>(al),
-                makeSubList(new CopyOnWriteArrayList<>(al)),
                 new ConcurrentLinkedQueue<>(al),
                 new ConcurrentLinkedDeque<>(al),
+
+                // Blocking Queues
+                abq,
                 new LinkedBlockingQueue<>(al),
                 new LinkedBlockingDeque<>(al),
                 new LinkedTransferQueue<>(al),
-                new PriorityBlockingQueue<>(al))
+                new PriorityBlockingQueue<>(al),
+
+                List.of(al.toArray(new Integer[0]))),
+
+            // avoid UnsupportedOperationException in jdk9 and jdk10
+            (goodClassName(immutableSubList).equals("RandomAccessSubList"))
+            ? Stream.empty()
+            : Stream.of(immutableSubList));
+
+        ArrayList<Job> jobs = collections
             .flatMap(x -> jobs(x))
             .filter(job ->
                 nameFilter == null || nameFilter.matcher(job.name()).find())
@@ -329,16 +355,29 @@
         return Stream.of(streams).flatMap(s -> s);
     }
 
+    boolean isMutable(Collection<Integer> x) {
+        return !(x.getClass().getName().contains("ImmutableCollections$"));
+    }
+
     Stream<Job> jobs(Collection<Integer> x) {
+        final String klazz = goodClassName(x);
         return concatStreams(
             collectionJobs(x),
 
+            (isMutable(x))
+            ? mutableCollectionJobs(x)
+            : Stream.empty(),
+
             (x instanceof Deque)
             ? dequeJobs((Deque<Integer>)x)
             : Stream.empty(),
 
             (x instanceof List)
             ? listJobs((List<Integer>)x)
+            : Stream.empty(),
+
+            (x instanceof List && isMutable(x))
+            ? mutableListJobs((List<Integer>)x)
             : Stream.empty());
     }
 
@@ -350,7 +389,7 @@
     }
 
     Stream<Job> collectionJobs(Collection<Integer> x) {
-        final String klazz = goodClassName(x.getClass());
+        final String klazz = goodClassName(x);
         return Stream.of(
             new Job(klazz + " iterate for loop") {
                 public void work() throws Throwable {
@@ -381,14 +420,6 @@
                         sum[0] = 0;
                         x.spliterator().forEachRemaining(n -> sum[0] += n);
                         check.sum(sum[0]);}}},
-            new Job(klazz + " removeIf") {
-                public void work() throws Throwable {
-                    int[] sum = new int[1];
-                    for (int i = 0; i < iterations; i++) {
-                        sum[0] = 0;
-                        if (x.removeIf(n -> { sum[0] += n; return false; }))
-                            throw new AssertionError();
-                        check.sum(sum[0]);}}},
             new Job(klazz + " contains") {
                 public void work() throws Throwable {
                     int[] sum = new int[1];
@@ -407,14 +438,6 @@
                         if (x.containsAll(sneakyAdderCollection))
                             throw new AssertionError();
                         check.sum(sum[0]);}}},
-            new Job(klazz + " remove(Object)") {
-                public void work() throws Throwable {
-                    int[] sum = new int[1];
-                    Object sneakyAdder = sneakyAdder(sum);
-                    for (int i = 0; i < iterations; i++) {
-                        sum[0] = 0;
-                        if (x.remove(sneakyAdder)) throw new AssertionError();
-                        check.sum(sum[0]);}}},
             new Job(klazz + " forEach") {
                 public void work() throws Throwable {
                     int[] sum = new int[1];
@@ -498,8 +521,29 @@
                         check.sum(sum[0]);}}});
     }
 
+    Stream<Job> mutableCollectionJobs(Collection<Integer> x) {
+        final String klazz = goodClassName(x);
+        return Stream.of(
+            new Job(klazz + " removeIf") {
+                public void work() throws Throwable {
+                    int[] sum = new int[1];
+                    for (int i = 0; i < iterations; i++) {
+                        sum[0] = 0;
+                        if (x.removeIf(n -> { sum[0] += n; return false; }))
+                            throw new AssertionError();
+                        check.sum(sum[0]);}}},
+            new Job(klazz + " remove(Object)") {
+                public void work() throws Throwable {
+                    int[] sum = new int[1];
+                    Object sneakyAdder = sneakyAdder(sum);
+                    for (int i = 0; i < iterations; i++) {
+                        sum[0] = 0;
+                        if (x.remove(sneakyAdder)) throw new AssertionError();
+                        check.sum(sum[0]);}}});
+    }
+
     Stream<Job> dequeJobs(Deque<Integer> x) {
-        String klazz = goodClassName(x.getClass());
+        final String klazz = goodClassName(x);
         return Stream.of(
             new Job(klazz + " descendingIterator() loop") {
                 public void work() throws Throwable {
@@ -519,7 +563,7 @@
     }
 
     Stream<Job> listJobs(List<Integer> x) {
-        final String klazz = goodClassName(x.getClass());
+        final String klazz = goodClassName(x);
         return Stream.of(
             new Job(klazz + " listIterator forward loop") {
                 public void work() throws Throwable {
@@ -555,15 +599,6 @@
                         if (x.lastIndexOf(sneakyAdder) != -1)
                             throw new AssertionError();
                         check.sum(sum[0]);}}},
-            new Job(klazz + " replaceAll") {
-                public void work() throws Throwable {
-                    int[] sum = new int[1];
-                    UnaryOperator<Integer> sneakyAdder =
-                        x -> { sum[0] += x; return x; };
-                    for (int i = 0; i < iterations; i++) {
-                        sum[0] = 0;
-                        x.replaceAll(sneakyAdder);
-                        check.sum(sum[0]);}}},
             new Job(klazz + " equals") {
                 public void work() throws Throwable {
                     ArrayList<Integer> copy = new ArrayList<>(x);
@@ -577,4 +612,18 @@
                         if (x.hashCode() != hashCode)
                             throw new AssertionError();}}});
     }
+
+    Stream<Job> mutableListJobs(List<Integer> x) {
+        final String klazz = goodClassName(x);
+        return Stream.of(
+            new Job(klazz + " replaceAll") {
+                public void work() throws Throwable {
+                    int[] sum = new int[1];
+                    UnaryOperator<Integer> sneakyAdder =
+                        x -> { sum[0] += x; return x; };
+                    for (int i = 0; i < iterations; i++) {
+                        sum[0] = 0;
+                        x.replaceAll(sneakyAdder);
+                        check.sum(sum[0]);}}});
+    }
 }