
int largest = Stream.of(points)
.filter(Points::isShort)
.mapToInt(Points::shortLengthSquared)
.max()
.orElseThrow();
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;
}
}
}

time or System.nanoTime$ mvn clean install $ java -jar target/benchmarks.jar FilterMap 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.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
hsdis-amd64.so from https://www.chriswhocodes.com/hsdis/export LD_LIBRARY_PATH=/opt/lib
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:+LogCompilation \
-XX:LogFile=jitwatch.log -cp target/classes/ --enable-preview \
com.horstmann.streams.demos.FilterMap 300000
export GDK_SCALE=2 java -jar /opt/jitwatch/jitwatch-ui-1.5.0-shaded-linux-x64.jar
forEachRemaining completely inlinedlimit after the map:
AbstractPipeline.copyInto. As before, set a breakpoint into line 566copyIntoWithCancel)forEachWithCancel
boolean cancelled;
do { } while (!(cancelled = sink.cancellationRequested()) && spliterator.tryAdvance(sink));
return cancelled;
StreamOpFlag.SHORT_CIRCUIT
FilterMapLimit.withArray avgt 100 664.089 ± 5.617 ms/op FilterMapLimit.withStream avgt 100 1169.370 ± 7.015 ms/op
java -jar target/benchmarks.jar \
-prof async:output=flamegraph\;libPath=/opt/async-profiler/lib/libasyncProfiler.so \
FilterMapLimit
Sink$ChainedReference.cancellationRequestedSink.cancellationRequested can't be inlinedint largest = Stream.of(points)
.parallel()
.filter(Points::isShort)
.mapToInt(Points::shortLengthSquared)
.max()
.orElseThrow();
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()
.orElseThrow();
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

gather for intermediate operationsIntStream.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]
var images = Stream.of(urls).gather(Gatherers.mapConcurrent(60, this::fetchImage)).toList()
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.offorEachRemaining, must check for cancellationvar result = listOfIntegers.parallelStream()
.map(...)
.gather(mapSequential(...))
.toList();
Benchmark Mode Cnt Score Error Units Gathering.parallelThenParallelizableGreedy avgt 25 396.633 ± 9.675 us/op Gathering.parallelThenParallelizablePicky avgt 25 425.897 ± 17.134 us/op Gathering.parallelThenSequentialGreedy avgt 25 771.995 ± 14.370 us/op Gathering.parallelThenSequentialPicky avgt 25 1739.768 ± 74.636 us/op Gathering.serialThenParallelizableGreedy avgt 25 1028.898 ± 15.994 us/op Gathering.serialThenParallelizablePicky avgt 25 1026.294 ± 10.314 us/op Gathering.serialThenSequentialGreedy avgt 25 1039.664 ± 20.719 us/op Gathering.serialThenSequentialPicky avgt 25 1084.909 ± 30.541 us/op