Sorry. Forgot to copy to the mailing list.

On Mon, Jun 2, 2025 at 7:27 AM Jige Yu <yuj...@gmail.com> wrote:

> Thanks Viktor!
>
> I was thinking from my own experience that I wouldn't have automatically
> assumed that a concurrent fanout library would by default preserve input
> order.
>
> And I think wanting high throughput with real-life utilities like race
> would be more commonly useful.
>
> But I could be wrong.
>
> Regardless, mapConcurrent() can do both, no?
>
> Even if it by default preserves input order, when I explicitly called
> stream.unordered(), could mapConcurrent() respect that and in return
> achieve higher throughput with support for race?
>
>
>
> On Mon, Jun 2, 2025 at 2:33 AM Viktor Klang <viktor.kl...@oracle.com>
> wrote:
>
>> Hi!
>>
>> In a similar vein to the built-in Collectors,
>> the built-in Gatherers provide solutions to common stream-related
>> problems, but also, they also serve as "inspiration" for developers for
>> what is possible to implement using Gatherers.
>>
>> If someone, for performance reasons, and with a use-case which does not
>> require encounter-order, want to take advantage of that combination of
>> circumstances, it is definitely possible to implement your own Gatherer
>> which has that behavior.
>>
>> Cheers,
>> √
>>
>>
>> *Viktor Klang*
>> Software Architect, Java Platform Group
>> Oracle
>> ------------------------------
>> *From:* core-libs-dev <core-libs-dev-r...@openjdk.org> on behalf of Jige
>> Yu <yuj...@gmail.com>
>> *Sent:* Sunday, 1 June 2025 21:08
>> *To:* core-libs-dev@openjdk.org <core-libs-dev@openjdk.org>
>> *Subject:* Should mapConcurrent() respect time order instead of input
>> order?
>>
>> It seems like for most people, input order isn't that important for
>> concurrent work, and concurrent results being in non-deterministic order is
>> often expected.
>>
>> If mapConcurrent() just respect output encounter order:
>>
>> It'll be able to achieve *higher throughput* if an early task is slow,
>> For example, with concurrency=2, and if the first task takes 10 minutes to
>> run, mapConcurrent() would only be able to process 2 tasks within the first
>> 10 minutes; whereas with encounter order, the first task being slow doesn't
>> block the 3rd - 100th elements from being processed and output.
>>
>> mapConcurrent() can be used to implement useful concurrent semantics, for
>> example to *support race* semantics. Imagine if I need to send request
>> to 10 candidate backends and take whichever that succeeds first, I'd be
>> able to do:
>>
>> backends.stream()
>>     .gather(mapConcurrent(
>>         backend -> {
>>           try {
>>             return backend.fetchOrder();
>>            } catch (RpcException e) {
>>              return null; // failed to fetch but not fatal
>>            }
>>         })
>>         .filter(Objects::notNull)
>>         .findFirst(); // first success then cancel the rest
>>
>>
>> Cheers,
>>
>>

Reply via email to