Fun with Spliterators

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Thu Oct 31 20:59:10 UTC 2024


Hi Doug,

I've been looking at the spliterators in the LBQ and other concurrent 
classes. I'm aware that the likelihood of anyone ever wanting to 
parallel stream over one of these is extremely remote, so this is just a 
curiosity.

In my experiment, I create 10m * hardware threads elements and put them 
into various collections. I then parallel stream over them and count how 
many times each thread executes is used.

Not surprisingly, the ArrayList does very well, since it is based on a 
sized and subsized array.

Some of the other collections were a bit surprising. Since I'm busy 
looking at the LBQ at the moment, here are its results:

LinkedBlockingQueue
ForkJoinPool.commonPool-worker-1=22242736 185.36%
ForkJoinPool.commonPool-worker-11=406 0.00%
ForkJoinPool.commonPool-worker-2=8169 0.07%
ForkJoinPool.commonPool-worker-3=23194669 193.29%
ForkJoinPool.commonPool-worker-4=22421660 186.85%
ForkJoinPool.commonPool-worker-5=79 0.00%
ForkJoinPool.commonPool-worker-6=24577826 204.82%
ForkJoinPool.commonPool-worker-7=27462223 228.85%
ForkJoinPool.commonPool-worker-9=92230 0.77%
main=2 0.00%
time = 985ms

We see that LBQ's parallel stream only used 10/12 cores and almost all 
the work was done by 5 threads.

In contrast, ArrayList:

ArrayList
ForkJoinPool.commonPool-worker-1=11250000 112.50%
ForkJoinPool.commonPool-worker-10=9375000 93.75%
ForkJoinPool.commonPool-worker-11=11250000 112.50%
ForkJoinPool.commonPool-worker-2=7500000 75.00%
ForkJoinPool.commonPool-worker-3=9375000 93.75%
ForkJoinPool.commonPool-worker-4=9375000 93.75%
ForkJoinPool.commonPool-worker-5=11250000 112.50%
ForkJoinPool.commonPool-worker-6=11250000 112.50%
ForkJoinPool.commonPool-worker-7=9375000 93.75%
ForkJoinPool.commonPool-worker-8=7500000 75.00%
ForkJoinPool.commonPool-worker-9=11250000 112.50%
main=11250000 112.50%
time = 287ms

This is, of course, not surprising, given the linked vs array based 
nature of the collections.

Here is my code for your amusement:

import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.stream.*;

public class LinkedBlockingQueueSpliterating {
     private static int ELEMENTS =
             10_000_000 * Runtime.getRuntime().availableProcessors();
     public static void main(String... args) {
         test(new ArrayBlockingQueue<>(ELEMENTS));
         test(new ArrayList<>());
         test(new LinkedList<>());
         test(new LinkedBlockingQueue<>());
         test(new ConcurrentLinkedQueue<>());
         test(new ConcurrentLinkedDeque<>());
         test(new ArrayDeque<>());
     }

     private static void test(Collection<Integer> collection) {
         System.out.println(collection.getClass().getSimpleName());
         for (int i = 0; i < ELEMENTS; i++) {
             collection.add(i);
         }
         long time = System.nanoTime();
         try {
             Map<String, Long> tasksPerThread =
                     collection.parallelStream()
                             .map(i -> Thread.currentThread().getName())
                             .collect(Collectors.groupingBy(
                                     Function.identity(),
                                     TreeMap::new,
                                     Collectors.counting()
                             ));
             int expectedTasksPerThread = collection.size() / 
tasksPerThread.size();
             for (var entry : tasksPerThread.entrySet()) {
                 System.out.printf("%s %.2f%%%n", entry,
                         100.0 * entry.getValue() / expectedTasksPerThread);
             }
         } finally {
             time = System.nanoTime() - time;
             System.out.printf("time = %dms%n%n", (time / 1_000_000));
         }
     }
}

Regards

Heinz
-- 
Dr Heinz M. Kabutz (PhD CompSci)
Author of "The Java™ Specialists' Newsletter" - www.javaspecialists.eu
Java Champion - www.javachampions.org
JavaOne Rock Star Speaker
Tel: +30 69 75 595 262
Skype: kabutz



More information about the concurrency-discuss mailing list