unordered()
Joe Bowbeer
joe.bowbeer at gmail.com
Mon Dec 24 17:01:51 PST 2012
Continuing with Uncle Bob's FP snippet:
(take 25 (squares-of (integers)))
I can code this in jdk8lambda-b69 as:
Function<Integer, Integer> square = (Integer i) -> i * i;
Stream<Integer> is = Streams.iterate(0, i -> i +
1).map(square).limit(25);
First, *note* that the following simplification won't compile because the
RHS creates an IntStream:
Stream<Integer> is = Streams.iterate(0, i -> i + 1).map((Integer i) ->
i * i).limit(25);
This is a bug, right?
Now something about unordered()..
When I add parallel() before the map() and print the result, I find that
the into() form creates ordered results no matter where I insert
unordered() in the pipeline, whereas forEach() already produces unordered
results.
1. Always ordered, regardless of unordered()
out.print(is.map(Object::toString).into(new StringJoiner(" ")));
=> 0 1 4 9 ... 441 484 529 576
2. Naturally unordered
is.forEach(i -> out.print(i + " "));
=> 0 529 576 441 ... 9 16 1 4
Seems weird.
-Joe
On Fri, Dec 21, 2012 at 2:13 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> So, the move to a more explicit choice of merging or concurrent tabulation
> also reduces (heh) the need for unordered(), though it does not eliminate
> it completely. (Limit, cancelation, and duplicate removal all have
> optimized versions if encounter order is not significant.)
>
> Kevin pointed out that .unordered() is pretty easy to miss, and people
> will not know that they don't know about it. One possible is to make it
> more explicit at one end of the pipeline or the other (the only operation
> that is order-injecting is sorted(), and presumably if you are sorting you
> really care about encounter order for the downstream ops, otherwise the
> sort was a waste of time.)
>
> The proposed tabulator / reducer stuff makes the order-sensitivity clear
> at the tail end, which is a good place to put it -- the user should know
> whether a reduce or a forEach is what they want -- if not the user, who?
> (Only the user knows whether he cares about order or not, and knows
> whether his combination functions are commutative or not.) The other
> less-ignorable place to put an ordering opt-out is at the head; we could
> make things more clear with adding
>
> .parallelUnorderedStream()
> alongside
> .stream()
> and
> .parallelStream()
>
> The obvious implementation of parallelUnorderdStream is:
>
> default Stream<E> parallelStream() {
> return stream().unordered();
> }
>
> which is also the most efficient place to put the .unordered (at the head.)
>
>
>
More information about the lambda-libs-spec-observers
mailing list