Whither FlatMapper?
Paul Sandoz
paul.sandoz at oracle.com
Thu Apr 11 05:09:58 PDT 2013
An initial version of StreamBuilder has been pushed:
http://hg.openjdk.java.net/lambda/lambda/jdk/rev/105d2c765fae
It is optimized for 0 and 1 elements (reused for singleton streams). In addition an optimization has been implemented when using forEach on the head of the stream. Those two optmizations should reduce the performance gap between the stream-based flatMap and the consumer-based flatMap.
Currently StreamBuilder does not allow for reuse, easy to add that though.
Paul.
On Apr 9, 2013, at 1:14 AM, Sam Pullara <spullara at gmail.com> wrote:
> That seems reasonable to me.
>
> Sam
>
> On Apr 8, 2013, at 4:02 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
>
>> Actually, there is an allocation-free path to get almost the Consumer-version performance with the non-consumer version, using the proposed StreamBuilder type (that also implements Spliterator and Stream, so "building" is allocation-free), and stuffing that into a ThreadLocal:
>>
>> ThreadLocal<StreamBuilder> tl = ...
>>
>> ...
>>
>> stream.flatMap(e -> {
>> StreamBuilder sb = tl.get();
>> sb.init();
>> // stuff elements into sb
>> return sb.build(); // basically a no-op
>> });
>>
>> So I recant my earlier statement that there's no efficient way to simulate the consumer form. Its just ugly.
>>
>> And the above can be captured by a wrapping helper:
>>
>> Function<T, Stream<U>> = wrapWithThreadLocalStreamBuilder(
>> (T t, Consumer<U> target) -> { /* old way */ });
>>
>> So, I'm even more firmly in the "remove it" camp.
>>
>> On 4/8/2013 4:05 PM, Brian Goetz wrote:
>>> A slight correction: if we remove the flatMap(FlatMapper), there is no
>>> fluent form that is as efficient as the removed form that accepts (T,
>>> Consumer<T>), since there's no other way to get your hands on the
>>> downstream Sink. (Not that this dampens my enthusiasm for removing it
>>> much.)
>>>
>>> For the truly diffident, a middle ground does exist: remove FlatMapper
>>> and its six brothers as a named SAM, and replace it with BiConsumer<T,
>>> Consumer<T>>, leaving both forms of flatMap methods in place:
>>> flatMap(Function<T,STream<U>>)
>>> flapMap(BiConsumer<T, Consumer<U>>)
>>>
>>> The main advantage being that the package javadoc is not polluted by
>>> seven forms of FlatMapper.
>>>
>>> On 4/8/2013 3:27 PM, Doug Lea wrote:
>>>> On 04/07/13 19:01, Sam Pullara wrote:
>>>>> I'm a big fan of the current FlatMapper stuff that takes a Consumer.
>>>>> Much more
>>>>> efficient and straightforward when you don't have a stream or
>>>>> collection to just
>>>>> return. Here is some code that uses 3 of them for good effect:
>>>>
>>>> I think the main issue is whether, given the user reactions so far, we
>>>> should insist on people using a generally better but non-obvious
>>>> approach to flat-mapping. Considering that anyone *could* write their own
>>>> FlatMappers layered on top of existing functionality (we could
>>>> even show how to do it as a code example somewhere), I'm with
>>>> Brian on this: give people the obvious forms in the API. People
>>>> who are most likely to use it are the least likely to be obsessive
>>>> about its performance. And when they are, they can learn about
>>>> alternatives.
>>>>
>>>> -Doug
>>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/attachments/20130411/0e52a8e9/attachment-0001.html
More information about the lambda-libs-spec-experts
mailing list