1/*
2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @summary micro-benchmark correctness mode
27 * @run main IteratorMicroBenchmark iterations=1 size=8 warmup=0
28 */
29
30import java.lang.ref.WeakReference;
31import java.util.ArrayDeque;
32import java.util.ArrayList;
33import java.util.Enumeration;
34import java.util.Iterator;
35import java.util.List;
36import java.util.ListIterator;
37import java.util.Map;
38import java.util.Spliterator;
39import java.util.Vector;
40import java.util.concurrent.ConcurrentSkipListMap;
41import java.util.concurrent.CountDownLatch;
42import java.util.concurrent.ThreadLocalRandom;
43import java.util.concurrent.TimeUnit;
44import java.util.regex.Pattern;
45
46/**
47 * Usage: [iterations=N] [size=N] [filter=REGEXP] [warmup=SECONDS]
48 *
49 * To run this in micro-benchmark mode, simply run as a normal java program.
50 * Be patient; this program runs for a very long time.
51 * For faster runs, restrict execution using command line args.
52 *
53 * @author Martin Buchholz
54 */
55public class IteratorMicroBenchmark {
56    abstract static class Job {
57        private final String name;
58        public Job(String name) { this.name = name; }
59        public String name() { return name; }
60        public abstract void work() throws Throwable;
61    }
62
63    static double warmupSeconds;
64    static long warmupNanos;
65
66    // --------------- GC finalization infrastructure ---------------
67
68    /** No guarantees, but effective in practice. */
69    static void forceFullGc() {
70        CountDownLatch finalizeDone = new CountDownLatch(1);
71        WeakReference<?> ref = new WeakReference<Object>(new Object() {
72            protected void finalize() { finalizeDone.countDown(); }});
73        try {
74            for (int i = 0; i < 10; i++) {
75                System.gc();
76                if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
77                    System.runFinalization(); // try to pick up stragglers
78                    return;
79                }
80            }
81        } catch (InterruptedException unexpected) {
82            throw new AssertionError("unexpected InterruptedException");
83        }
84        throw new AssertionError("failed to do a \"full\" gc");
85    }
86
87    /**
88     * Runs each job for long enough that all the runtime compilers
89     * have had plenty of time to warm up, i.e. get around to
90     * compiling everything worth compiling.
91     * Returns array of average times per job per run.
92     */
93    private static long[] time0(Job ... jobs) throws Throwable {
94        long[] nanoss = new long[jobs.length];
95        for (int i = 0; i < jobs.length; i++) {
96            if (warmupNanos > 0) forceFullGc();
97            Job job = jobs[i];
98            long totalTime;
99            int runs = 0;
100            long startTime = System.nanoTime();
101            do { job.work(); runs++; }
102            while ((totalTime = System.nanoTime() - startTime) < warmupNanos);
103            nanoss[i] = totalTime/runs;
104        }
105        return nanoss;
106    }
107
108    private static void time(Job ... jobs) throws Throwable {
109        if (warmupSeconds > 0.0) time0(jobs); // Warm up run
110        long[] nanoss = time0(jobs); // Real timing run
111        long[] milliss = new long[jobs.length];
112        double[] ratios = new double[jobs.length];
113
114        final String nameHeader   = "Method";
115        final String millisHeader = "Millis";
116        final String ratioHeader  = "Ratio";
117
118        int nameWidth   = nameHeader.length();
119        int millisWidth = millisHeader.length();
120        int ratioWidth  = ratioHeader.length();
121
122        for (int i = 0; i < jobs.length; i++) {
123            nameWidth = Math.max(nameWidth, jobs[i].name().length());
124
125            milliss[i] = nanoss[i]/(1000L * 1000L);
126            millisWidth = Math.max(millisWidth,
127                                   String.format("%d", milliss[i]).length());
128
129            ratios[i] = (double) nanoss[i] / (double) nanoss[0];
130            ratioWidth = Math.max(ratioWidth,
131                                  String.format("%.3f", ratios[i]).length());
132        }
133
134        String format = String.format("%%-%ds %%%dd %%%d.3f%%n",
135                                      nameWidth, millisWidth, ratioWidth);
136        String headerFormat = String.format("%%-%ds %%%ds %%%ds%%n",
137                                            nameWidth, millisWidth, ratioWidth);
138        System.out.printf(headerFormat, "Method", "Millis", "Ratio");
139
140        // Print out absolute and relative times, calibrated against first job
141        for (int i = 0; i < jobs.length; i++)
142            System.out.printf(format, jobs[i].name(), milliss[i], ratios[i]);
143    }
144
145    private static String keywordValue(String[] args, String keyword) {
146        for (String arg : args)
147            if (arg.startsWith(keyword))
148                return arg.substring(keyword.length() + 1);
149        return null;
150    }
151
152    private static int intArg(String[] args, String keyword, int defaultValue) {
153        String val = keywordValue(args, keyword);
154        return (val == null) ? defaultValue : Integer.parseInt(val);
155    }
156
157    private static double doubleArg(String[] args, String keyword, double defaultValue) {
158        String val = keywordValue(args, keyword);
159        return (val == null) ? defaultValue : Double.parseDouble(val);
160    }
161
162    private static Pattern patternArg(String[] args, String keyword) {
163        String val = keywordValue(args, keyword);
164        return (val == null) ? null : Pattern.compile(val);
165    }
166
167    private static Job[] filter(Pattern filter, Job[] jobs) {
168        if (filter == null) return jobs;
169        Job[] newJobs = new Job[jobs.length];
170        int n = 0;
171        for (Job job : jobs)
172            if (filter.matcher(job.name()).find())
173                newJobs[n++] = job;
174        // Arrays.copyOf not available in JDK 5
175        Job[] ret = new Job[n];
176        System.arraycopy(newJobs, 0, ret, 0, n);
177        return ret;
178    }
179
180    private static void deoptimize(int sum) {
181        if (sum == 42)
182            System.out.println("the answer");
183    }
184
185    private static <T> List<T> asSubList(List<T> list) {
186        return list.subList(0, list.size());
187    }
188
189    private static <T> Iterable<T> backwards(final List<T> list) {
190        return new Iterable<T>() {
191            public Iterator<T> iterator() {
192                return new Iterator<T>() {
193                    final ListIterator<T> it = list.listIterator(list.size());
194                    public boolean hasNext() { return it.hasPrevious(); }
195                    public T next()          { return it.previous(); }
196                    public void remove()     {        it.remove(); }};}};
197    }
198
199    public static void main(String[] args) throws Throwable {
200        final int iterations = intArg(args, "iterations", 100_000);
201        final int size       = intArg(args, "size", 1000);
202        warmupSeconds        = doubleArg(args, "warmup", 7.0);
203        final Pattern filter = patternArg(args, "filter");
204
205        warmupNanos = (long) (warmupSeconds * (1000L * 1000L * 1000L));
206
207//         System.out.printf(
208//             "iterations=%d size=%d, warmup=%1g, filter=\"%s\"%n",
209//             iterations, size, warmupSeconds, filter);
210
211        final ConcurrentSkipListMap<Integer,Integer> m
212            = new ConcurrentSkipListMap<>();
213        final ArrayList<Integer> al = new ArrayList<>(size);
214
215        // Populate collections with random data
216        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
217        for (int i = 0; i < size; i++) {
218            m.put(rnd.nextInt(size), rnd.nextInt(size));
219            al.add(rnd.nextInt(size));
220        }
221        final Vector<Integer> v = new Vector<>(al);
222        final ArrayDeque<Integer> ad = new ArrayDeque<>(al);
223        // shuffle ArrayDeque elements so they wrap
224        for (int i = 0, n = rnd.nextInt(size); i < n; i++)
225            ad.addLast(ad.removeFirst());
226
227        // Also test "short" collections
228        final int shortSize = 5;
229        final Vector<Integer> sv = new Vector<>(v.subList(0, shortSize));
230        final ArrayList<Integer> sal = new ArrayList<>(sv);
231
232        // Checks for correctness *and* prevents loop optimizations
233        class Check {
234            private int sum;
235            public void sum(int sum) {
236                if (this.sum == 0)
237                    this.sum = sum;
238                if (this.sum != sum)
239                    throw new AssertionError("Sum mismatch");
240            }
241        }
242        final Check check      = new Check();
243        final Check shortCheck = new Check();
244
245        Job[] jobs = {
246//          new Job("Vector iterate desugared") {
247//              public void work() throws Throwable {
248//                  for (int i = 0; i < iterations; i++) {
249//                      int sum = 0;
250//                      for (Iterator<Integer> it = v.iterator(); it.hasNext();)
251//                          sum += it.next();
252//                      check.sum(sum);}}},
253            new Job("array loop") {
254                public void work() throws Throwable {
255                    Integer[] a = al.toArray(new Integer[0]);
256                    for (int i = 0; i < iterations; i++) {
257                        int sum = 0;
258                        int size = a.length;
259                        for (int j = 0; j < size; ++j)
260                            sum += a[j];
261                        check.sum(sum);}}},
262            new Job("descending array loop") {
263                public void work() throws Throwable {
264                    Integer[] a = al.toArray(new Integer[0]);
265                    for (int i = 0; i < iterations; i++) {
266                        int sum = 0;
267                        int size = a.length;
268                        for (int j = size - 1; j >= 0; j--)
269                            sum += a[j];
270                        check.sum(sum);}}},
271            new Job("Vector get loop") {
272                public void work() throws Throwable {
273                    for (int i = 0; i < iterations; i++) {
274                        int sum = 0;
275                        int size = v.size();
276                        for (int j = 0; j < size; ++j)
277                            sum += v.get(j);
278                        check.sum(sum);}}},
279            new Job("Vector iterate for loop") {
280                public void work() throws Throwable {
281                    for (int i = 0; i < iterations; i++) {
282                        int sum = 0;
283                        for (Integer n : v)
284                            sum += n;
285                        check.sum(sum);}}},
286            new Job("Vector descending listIterator loop") {
287                public void work() throws Throwable {
288                    for (int i = 0; i < iterations; i++) {
289                        int sum = 0;
290                        ListIterator<Integer> it = v.listIterator(al.size());
291                        while (it.hasPrevious())
292                            sum += it.previous();
293                        check.sum(sum);}}},
294            new Job("Vector Enumeration loop") {
295                public void work() throws Throwable {
296                    for (int i = 0; i < iterations; i++) {
297                        int sum = 0;
298                        Enumeration<Integer> it = v.elements();
299                        while (it.hasMoreElements())
300                            sum += it.nextElement();
301                        check.sum(sum);}}},
302            new Job("Vector subList iterate for loop") {
303                public void work() throws Throwable {
304                    for (int i = 0; i < iterations; i++) {
305                        int sum = 0;
306                        for (Integer n : asSubList(v))
307                            sum += n;
308                        check.sum(sum);}}},
309            new Job("Vector subList subList subList iterate for loop") {
310                public void work() throws Throwable {
311                    for (int i = 0; i < iterations; i++) {
312                        int sum = 0;
313                        for (Integer n : asSubList(asSubList(asSubList(v))))
314                            sum += n;
315                        check.sum(sum);}}},
316            new Job("Vector backwards wrapper ListIterator for loop") {
317                public void work() throws Throwable {
318                    for (int i = 0; i < iterations; i++) {
319                        int sum = 0;
320                        for (Integer n : backwards(v))
321                            sum += n;
322                        check.sum(sum);}}},
323            new Job("Vector backwards wrapper subList ListIterator for loop") {
324                public void work() throws Throwable {
325                    for (int i = 0; i < iterations; i++) {
326                        int sum = 0;
327                        for (Integer n : backwards(asSubList(v)))
328                            sum += n;
329                        check.sum(sum);}}},
330//          new Job("Vector iterate for loop invokeinterface") {
331//              public void work() throws Throwable {
332//                  final List<Integer> l = v;
333//                  for (int i = 0; i < iterations; i++) {
334//                      int sum = 0;
335//                      for (Integer n : l)
336//                          sum += n;
337//                      check.sum(sum);}}},
338//          new Job("Vector subList iterate for loop invokeinterface") {
339//              public void work() throws Throwable {
340//                  final List<Integer> l = v;
341//                  for (int i = 0; i < iterations; i++) {
342//                      int sum = 0;
343//                      for (Integer n : asSubList(l))
344//                          sum += n;
345//                      check.sum(sum);}}},
346            new Job("Short Vector get loop") {
347                public void work() throws Throwable {
348                    for (int i = 0; i < (iterations * size / shortSize); i++) {
349                        int sum = 0;
350                        int size = sv.size();
351                        for (int j = 0; j < size; ++j)
352                            sum += sv.get(j);
353                        shortCheck.sum(sum);}}},
354            new Job("Short Vector iterate for loop") {
355                public void work() throws Throwable {
356                    for (int i = 0; i < (iterations * size / shortSize); i++) {
357                        int sum = 0;
358                        for (Integer n : sv)
359                            sum += n;
360                        shortCheck.sum(sum);}}},
361            new Job("Short Vector sublist iterate for loop") {
362                public void work() throws Throwable {
363                    for (int i = 0; i < (iterations * size / shortSize); i++) {
364                        int sum = 0;
365                        for (Integer n : asSubList(sv))
366                            sum += n;
367                        shortCheck.sum(sum);}}},
368            new Job("ArrayList get loop") {
369                public void work() throws Throwable {
370                    for (int i = 0; i < iterations; i++) {
371                        int sum = 0;
372                        int size = al.size();
373                        for (int j = 0; j < size; ++j)
374                            sum += al.get(j);
375                        check.sum(sum);}}},
376            new Job("ArrayList iterate for loop") {
377                public void work() throws Throwable {
378                    for (int i = 0; i < iterations; i++) {
379                        int sum = 0;
380                        for (Integer n : al)
381                            sum += n;
382                        check.sum(sum);}}},
383            new Job("ArrayDeque iterate for loop") {
384                public void work() throws Throwable {
385                    for (int i = 0; i < iterations; i++) {
386                        int sum = 0;
387                        for (Integer n : ad)
388                            sum += n;
389                        check.sum(sum);}}},
390            new Job("ArrayList descending listIterator loop") {
391                public void work() throws Throwable {
392                    for (int i = 0; i < iterations; i++) {
393                        int sum = 0;
394                        ListIterator<Integer> it = al.listIterator(al.size());
395                        while (it.hasPrevious())
396                            sum += it.previous();
397                        check.sum(sum);}}},
398            new Job("ArrayList listIterator loop") {
399                public void work() throws Throwable {
400                    for (int i = 0; i < iterations; i++) {
401                        int sum = 0;
402                        ListIterator<Integer> it = al.listIterator();
403                        while (it.hasNext())
404                            sum += it.next();
405                        check.sum(sum);}}},
406            new Job("ArrayDeque.descendingIterator() loop") {
407                public void work() throws Throwable {
408                    for (int i = 0; i < iterations; i++) {
409                        int sum = 0;
410                        Iterator<Integer> it = ad.descendingIterator();
411                        while (it.hasNext())
412                            sum += it.next();
413                        check.sum(sum);}}},
414            new Job("ArrayList.forEach") {
415                public void work() throws Throwable {
416                    int[] sum = new int[1];
417                    for (int i = 0; i < iterations; i++) {
418                        sum[0] = 0;
419                        al.forEach(n -> sum[0] += n);
420                        check.sum(sum[0]);}}},
421            new Job("ArrayDeque.forEach") {
422                public void work() throws Throwable {
423                    int[] sum = new int[1];
424                    for (int i = 0; i < iterations; i++) {
425                        sum[0] = 0;
426                        ad.forEach(n -> sum[0] += n);
427                        check.sum(sum[0]);}}},
428            new Job("Vector.forEach") {
429                public void work() throws Throwable {
430                    int[] sum = new int[1];
431                    for (int i = 0; i < iterations; i++) {
432                        sum[0] = 0;
433                        v.forEach(n -> sum[0] += n);
434                        check.sum(sum[0]);}}},
435            new Job("ArrayList.iterator().forEachRemaining()") {
436                public void work() throws Throwable {
437                    int[] sum = new int[1];
438                    for (int i = 0; i < iterations; i++) {
439                        sum[0] = 0;
440                        al.iterator().forEachRemaining(n -> sum[0] += n);
441                        check.sum(sum[0]);}}},
442            new Job("ArrayDeque.descendingIterator().forEachRemaining()") {
443                public void work() throws Throwable {
444                    int[] sum = new int[1];
445                    for (int i = 0; i < iterations; i++) {
446                        sum[0] = 0;
447                        ad.descendingIterator().forEachRemaining(n -> sum[0] += n);
448                        check.sum(sum[0]);}}},
449            new Job("ArrayDeque.iterator().forEachRemaining()") {
450                public void work() throws Throwable {
451                    int[] sum = new int[1];
452                    for (int i = 0; i < iterations; i++) {
453                        sum[0] = 0;
454                        ad.iterator().forEachRemaining(n -> sum[0] += n);
455                        check.sum(sum[0]);}}},
456            new Job("Vector.iterator().forEachRemaining()") {
457                public void work() throws Throwable {
458                    int[] sum = new int[1];
459                    for (int i = 0; i < iterations; i++) {
460                        sum[0] = 0;
461                        v.iterator().forEachRemaining(n -> sum[0] += n);
462                        check.sum(sum[0]);}}},
463            new Job("ArrayList.spliterator().forEachRemaining()") {
464                public void work() throws Throwable {
465                    int[] sum = new int[1];
466                    for (int i = 0; i < iterations; i++) {
467                        sum[0] = 0;
468                        al.spliterator().forEachRemaining(n -> sum[0] += n);
469                        check.sum(sum[0]);}}},
470            new Job("ArrayDeque.spliterator().forEachRemaining()") {
471                public void work() throws Throwable {
472                    int[] sum = new int[1];
473                    for (int i = 0; i < iterations; i++) {
474                        sum[0] = 0;
475                        ad.spliterator().forEachRemaining(n -> sum[0] += n);
476                        check.sum(sum[0]);}}},
477            new Job("Vector.spliterator().forEachRemaining()") {
478                public void work() throws Throwable {
479                    int[] sum = new int[1];
480                    for (int i = 0; i < iterations; i++) {
481                        sum[0] = 0;
482                        v.spliterator().forEachRemaining(n -> sum[0] += n);
483                        check.sum(sum[0]);}}},
484            new Job("ArrayList.spliterator().tryAdvance()") {
485                public void work() throws Throwable {
486                    int[] sum = new int[1];
487                    for (int i = 0; i < iterations; i++) {
488                        sum[0] = 0;
489                        Spliterator<Integer> spliterator = al.spliterator();
490                        do {} while (spliterator.tryAdvance(n -> sum[0] += n));
491                        check.sum(sum[0]);}}},
492            new Job("ArrayDeque.spliterator().tryAdvance()") {
493                public void work() throws Throwable {
494                    int[] sum = new int[1];
495                    for (int i = 0; i < iterations; i++) {
496                        sum[0] = 0;
497                        Spliterator<Integer> spliterator = ad.spliterator();
498                        do {} while (spliterator.tryAdvance(n -> sum[0] += n));
499                        check.sum(sum[0]);}}},
500            new Job("Vector.spliterator().tryAdvance()") {
501                public void work() throws Throwable {
502                    int[] sum = new int[1];
503                    for (int i = 0; i < iterations; i++) {
504                        sum[0] = 0;
505                        Spliterator<Integer> spliterator = v.spliterator();
506                        do {} while (spliterator.tryAdvance(n -> sum[0] += n));
507                        check.sum(sum[0]);}}},
508            new Job("ArrayList.removeIf") {
509                public void work() throws Throwable {
510                    int[] sum = new int[1];
511                    for (int i = 0; i < iterations; i++) {
512                        sum[0] = 0;
513                        al.removeIf(n -> { sum[0] += n; return false; });
514                        check.sum(sum[0]);}}},
515            new Job("ArrayDeque.removeIf") {
516                public void work() throws Throwable {
517                    int[] sum = new int[1];
518                    for (int i = 0; i < iterations; i++) {
519                        sum[0] = 0;
520                        ad.removeIf(n -> { sum[0] += n; return false; });
521                        check.sum(sum[0]);}}},
522            new Job("Vector.removeIf") {
523                public void work() throws Throwable {
524                    int[] sum = new int[1];
525                    for (int i = 0; i < iterations; i++) {
526                        sum[0] = 0;
527                        v.removeIf(n -> { sum[0] += n; return false; });
528                        check.sum(sum[0]);}}},
529            new Job("ArrayList subList .removeIf") {
530                public void work() throws Throwable {
531                    int[] sum = new int[1];
532                    List<Integer> sl = asSubList(al);
533                    for (int i = 0; i < iterations; i++) {
534                        sum[0] = 0;
535                        sl.removeIf(n -> { sum[0] += n; return false; });
536                        check.sum(sum[0]);}}},
537            new Job("ArrayList subList get loop") {
538                public void work() throws Throwable {
539                    List<Integer> sl = asSubList(al);
540                    for (int i = 0; i < iterations; i++) {
541                        int sum = 0;
542                        int size = sl.size();
543                        for (int j = 0; j < size; ++j)
544                            sum += sl.get(j);
545                        check.sum(sum);}}},
546            new Job("ArrayList subList iterate for loop") {
547                public void work() throws Throwable {
548                    for (int i = 0; i < iterations; i++) {
549                        int sum = 0;
550                        for (Integer n : asSubList(al))
551                            sum += n;
552                        check.sum(sum);}}},
553            new Job("ArrayList subList subList subList iterate for loop") {
554                public void work() throws Throwable {
555                    for (int i = 0; i < iterations; i++) {
556                        int sum = 0;
557                        for (Integer n : asSubList(asSubList(asSubList(al))))
558                            sum += n;
559                        check.sum(sum);}}},
560            new Job("ArrayList backwards wrapper ListIterator for loop") {
561                public void work() throws Throwable {
562                    for (int i = 0; i < iterations; i++) {
563                        int sum = 0;
564                        for (Integer n : backwards(al))
565                            sum += n;
566                        check.sum(sum);}}},
567            new Job("ArrayList backwards wrapper subList ListIterator for loop") {
568                public void work() throws Throwable {
569                    for (int i = 0; i < iterations; i++) {
570                        int sum = 0;
571                        for (Integer n : backwards(asSubList(al)))
572                            sum += n;
573                        check.sum(sum);}}},
574//          new Job("ArrayList iterate desugared") {
575//              public void work() throws Throwable {
576//                  for (int i = 0; i < iterations; i++) {
577//                      int sum = 0;
578//                      for (Iterator<Integer> it = al.iterator(); it.hasNext();)
579//                          sum += it.next();
580//                      check.sum(sum);}}},
581            new Job("Short ArrayList get loop") {
582                public void work() throws Throwable {
583                    for (int i = 0; i < (iterations * size / shortSize); i++) {
584                        int sum = 0;
585                        int size = sal.size();
586                        for (int j = 0; j < size; ++j)
587                            sum += sal.get(j);
588                        shortCheck.sum(sum);}}},
589            new Job("Short ArrayList iterate for loop") {
590                public void work() throws Throwable {
591                    for (int i = 0; i < (iterations * size / shortSize); i++) {
592                        int sum = 0;
593                        for (Integer n : sal)
594                            sum += n;
595                        shortCheck.sum(sum);}}},
596            new Job("Short ArrayList sublist iterate for loop") {
597                public void work() throws Throwable {
598                    for (int i = 0; i < (iterations * size / shortSize); i++) {
599                        int sum = 0;
600                        for (Integer n : asSubList(sal))
601                            sum += n;
602                        shortCheck.sum(sum);}}},
603            new Job("Vector ArrayList alternating iteration") {
604                public void work() throws Throwable {
605                    for (int i = 0; i < iterations; i++) {
606                        int sum = 0;
607                        Iterator<Integer> it1 = v.iterator();
608                        Iterator<Integer> it2 = al.iterator();
609                        while (it1.hasNext())
610                            sum += it1.next() + it2.next();
611                        check.sum(sum/2);}}},
612            new Job("Vector ArrayList alternating invokeVirtual iteration") {
613                public void work() throws Throwable {
614                    for (int i = 0; i < iterations; i++) {
615                        int sum = 0;
616                        List<Iterator<Integer>> its = new ArrayList<>(2);
617                        its.add(v.iterator());
618                        its.add(al.iterator());
619                        for (int k = 0; its.get(k).hasNext(); k = (k == 0) ? 1 : 0)
620                            sum += its.get(k).next();
621                        check.sum(sum/2);}}},
622            new Job("ConcurrentSkipListMap entrySet iterate") {
623                public void work() throws Throwable {
624                    for (int i = 0; i < iterations; i++) {
625                        int sum = 0;
626                        for (Map.Entry<Integer,Integer> e : m.entrySet())
627                            sum += e.getKey();
628                        deoptimize(sum);}}},
629            new Job("ArrayList.toArray()") {
630                public void work() throws Throwable {
631                    int[] sum = new int[1];
632                    for (int i = 0; i < iterations; i++) {
633                        sum[0] = 0;
634                        for (Object o : al.toArray())
635                            sum[0] += (Integer) o;
636                        check.sum(sum[0]);}}},
637            new Job("ArrayList.toArray(a)") {
638                public void work() throws Throwable {
639                    Integer[] a = new Integer[size];
640                    int[] sum = new int[1];
641                    for (int i = 0; i < iterations; i++) {
642                        sum[0] = 0;
643                        al.toArray(a);
644                        for (Object o : a)
645                            sum[0] += (Integer) o;
646                        check.sum(sum[0]);}}},
647            new Job("ArrayDeque.toArray()") {
648                public void work() throws Throwable {
649                    int[] sum = new int[1];
650                    for (int i = 0; i < iterations; i++) {
651                        sum[0] = 0;
652                        for (Object o : ad.toArray())
653                            sum[0] += (Integer) o;
654                        check.sum(sum[0]);}}},
655            new Job("ArrayDeque.toArray(a)") {
656                public void work() throws Throwable {
657                    Integer[] a = new Integer[size];
658                    int[] sum = new int[1];
659                    for (int i = 0; i < iterations; i++) {
660                        sum[0] = 0;
661                        ad.toArray(a);
662                        for (Object o : a)
663                            sum[0] += (Integer) o;
664                        check.sum(sum[0]);}}},
665            new Job("Vector.toArray()") {
666                public void work() throws Throwable {
667                    int[] sum = new int[1];
668                    for (int i = 0; i < iterations; i++) {
669                        sum[0] = 0;
670                        for (Object o : v.toArray())
671                            sum[0] += (Integer) o;
672                        check.sum(sum[0]);}}},
673            new Job("Vector.toArray(a)") {
674                public void work() throws Throwable {
675                    Integer[] a = new Integer[size];
676                    int[] sum = new int[1];
677                    for (int i = 0; i < iterations; i++) {
678                        sum[0] = 0;
679                        v.toArray(a);
680                        for (Object o : a)
681                            sum[0] += (Integer) o;
682                        check.sum(sum[0]);}}},
683        };
684
685        time(filter(filter, jobs));
686    }
687}
688