

int largest = Stream.of(points)
.filter(Points::isShort)
.mapToInt(Points::shortLengthSquared)
.max()
.orElse(Integer.MIN_VALUE);
int largest = Integer.MIN_VALUE;
for (int i = 0; i < points.length; i++) {
Point p = points[i];
if (Points.isShort(p)) {
int lengthSquared = Points.shortLengthSquared(p);
if (lengthSquared > largest) {
largest = lengthSquared;
}
}
}
Benchmark Mode Cnt Score Error Units FilterMap.withArray avgt 100 1711.600 Β± 10.471 ms/op FilterMap.withStream avgt 100 1798.188 Β± 11.118 ms/op
FilterMap demo, set breakpoint to .filter(...)new StatelessOp<>(...).accept method of sink..map(...)new StatelessOp<>(...). Look at accept method.max, the terminal op. Skipping a few steps, set a breakpoint in AbstractPipeline.copyInto (line 566)spliterator.forEachRemaining(wrappedSink);
forEachRemainingaction.accept: First pipeline stage checks the filter predicatedownstream.accept(u) and resume (F9)ReducingSink accepts the element, updating the maximum
limit after the map:
FilterMapLimit.withArray avgt 100 664.089 Β± 5.617 ms/op FilterMapLimit.withStream avgt 100 1169.370 Β± 7.015 ms/op
forEachRemaining:
boolean cancelled;
do { } while (!(cancelled = sink.cancellationRequested()) && spliterator.tryAdvance(sink));
return cancelled;
java -jar target/benchmarks.jar \
-prof async:output=flamegraph\;libPath=/opt/async-profiler/lib/libasyncProfiler.so \
FilterMapLimit
Sink$ChainedReference.cancellationRequestedSink.cancellationRequested can't be inlined
var words = Files.lines(Path.of(textFile))
.flatMap(l -> Stream.of(l.split(" "))) // A stream for every line
.toList();
result = points.stream().map(p -> Math.hypot(p.x(), p.y())).reduce(0.0, Double::sum); // π result = points.stream().mapToDouble(p -> Math.hypot(p.x(), p.y())).sum(); // π
distinct, sorted must buffer elements
int largest = Stream.of(points)
.parallel()
.filter(Points::isShort)
.mapToInt(Points::shortLengthSquared)
.max()
.orElse(Integer.MIN_VALUE);
Benchmark Mode Cnt Score Error Units ParallelFilterMap.withParallelStream avgt 100 154229.126 Β± 2323.488 us/op ParallelFilterMap.withSerialStream avgt 100 1828765.262 Β± 9945.505 us/op
long result = Stream.of(points)
.parallel()
.mapToLong(Points::lengthSquared)
.filter(p -> p < DIST)
.limit(POINTS / 10)
.max()
.orElse(Integer.MIN_VALUE);
ParallelMapFilterLimit.withParallelStream avgt 100 275946.600 Β± 14045.715 us/op ParallelMapFilterLimit.withSerialStream avgt 100 236369.864 Β± 2717.238 us/op
long result = Stream.of(state.points)
.parallel()
.unordered()
...
ParallelMapFilterLimit.withUnorderedParallelStream avgt 100 56743.103 Β± 1841.688 us/op
Files.linesFiles.lines(Path.of(filename))
.parallel()
.collect(Collectors.groupingBy(l -> Thread.currentThread().toString(),
Collectors.counting()))
.forEach((k,v) -> System.out.printf("%-40s %15d%n", k, v))
ForkJoinPool.commonPool-worker-29 16262697 ForkJoinPool.commonPool-worker-13 16616234 ForkJoinPool.commonPool-worker-11 16828071 ForkJoinPool.commonPool-worker-5 17058156 ForkJoinPool.commonPool-worker-23 16262697 ForkJoinPool.commonPool-worker-15 17550581 ForkJoinPool.commonPool-worker-17 17676845 ForkJoinPool.commonPool-worker-31 13434402 ForkJoinPool.commonPool-worker-1 16262698 ForkJoinPool.commonPool-worker-25 13411912 ForkJoinPool.commonPool-worker-9 16969771 ForkJoinPool.commonPool-worker-19 16969771 ForkJoinPool.commonPool-worker-27 16262698
ForkJoinPool.commonPool-worker-29 58368 ForkJoinPool.commonPool-worker-13 50244608 ForkJoinPool.commonPool-worker-11 62464 ForkJoinPool.commonPool-worker-5 41984 ForkJoinPool.commonPool-worker-23 266399744 ForkJoinPool.commonPool-worker-15 140628992 ForkJoinPool.commonPool-worker-17 237836288 ForkJoinPool.commonPool-worker-31 40960 ForkJoinPool.commonPool-worker-1 60416 ForkJoinPool.commonPool-worker-25 216946688 ForkJoinPool.commonPool-worker-9 33792 ForkJoinPool.commonPool-worker-27 34816 ForkJoinPool.commonPool-worker-3 161350656
Files.lines optimized for files up to 2GBString task(int i) {
try {
Thread.sleep(1000);
} catch (InterruptedException _) {
}
return i + " " + Thread.currentThread().toString();
}
IntStream.range(0, 60).mapToObj(this::task).toList()
IntStream.range(0, 60).parallel().mapToObj(this::task).toList()
IntStream.range(0, 60).boxed().gather(Gatherers.mapConcurrent(60, this::task)).toList()
var result = IntStream.range(0, 100)
.boxed()
.gather(Gatherers.mapConcurrent(10, this::task))
.limit(20)
.toList();
gather can't throw an InterruptedException
gather for intermediate operationsmapConcurrentIntStream.range(0, 10).boxed().gather(Gatherers.windowFixed(4)).toList()
// [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]
IntStream.range(0, 10).boxed().gather(Gatherers.windowSliding(4)).toList()
// [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9]]
Integer[] digits = { 1, 7, 2, 9 };
Stream.of(digits).gather(Gatherers.scan(() -> 0, (x, y) -> x * 10 + y)) // [1, 17, 172, 1729]
Stream.of(digits).gather(Gatherers.fold(() -> 0, (x, y) -> x * 10 + y)) // [1729]
static <T> Gatherer<T, ?, Map.Entry<Long, T> zipWithIndex() {
class Index { long index = 0; }
return Gatherer.ofSequential(
Index::new,
Gatherer.Integrator.ofGreedy((state, element, downstream) ->
return downstream.push(Map.entry(state.index++, element))));
}
Gatherer.ofSequential/Gatherer.ofwindowSliding, zipWithIndexGatherer.Integrator.ofGreedy/Gatherer.Integrator.offlatMap is never parallel:
var users = List.of("Alice", "Bob");
var result = users.stream()
.flatMap(user ->
IntStream.range(1, 100)
.boxed()
.parallel() // Ignored
.map(id -> "%s β %d (%s)".formatted(user, id, Thread.currentThread().getName()))
)
.toList();
[Alice β 1 (main), Alice β 2 (main), ..., Bob β 99 (main)]
flatMap on a parallel unordered stream:
IntStream.range(0, 10)
.boxed()
.parallel()
.unordered()
.flatMap(i -> IntStream.range(0, i).boxed().peek(IO::println))
.limit(10)
.toList(); // [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
0 0 0 0 1 0 0 1 2 3 1 2 3 1 0 1 2 3 1 2 1 2 0 4 0 1 2 3 4 4 5 6 7 2 3 4 5 5 6 7 3 4 5 8 6
List<String> sample = Files.lines(Path.of(largeFile))
.parallel()
.gather(Gatherers.windowFixed(SAMPLE_SIZE))
.findAny();
java.lang.OutOfMemoryErrorlimit, sorted, etc.unordered()Stream.of(0)
.parallel()
.unordered()
.flatMap(_ -> Stream.generate(() -> 0))
.skip(10)
.findFirst(); // OOM

