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, >> >>