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