<div dir="ltr"><p>Hi Viktor,</p><p>Thanks for your reply and for sharing your experience regarding user preferences. I appreciate that perspective.</p><p>You're right, if an unordered version of <code>mapConcurrent</code> proves to be widely beneficial and is implemented and adopted by the community, it could certainly make a strong case for future inclusion in the JDK.</p><p>I wanted to clarify a nuance regarding user preference that I might not have articulated clearly before. If the question is simply "ordered or unordered?", in isolation, I can see why many, myself included, might lean towards "ordered" as a general preference.</p><p>However, the decision becomes more complex when the associated trade-offs are considered. If the question were phrased more like, "Do you prefer an ordered <code>mapConcurrent</code> by default, even if it entails potential performance overhead and limitations for certain use cases like <code>race()</code> operations, versus an unordered version that offers higher throughput and broader applicability in such scenarios?" my (and perhaps others') answer might differ. The perceived cost versus benefit of ordering changes significantly when these factors are explicit.</p><p>My initial suggestion stemmed from the belief that the performance and flexibility gains of an unordered approach for I/O-bound tasks would, in many practical situations, outweigh the convenience of default ordering, especially since ordering can be reintroduced relatively easily, and explicitly, when needed.</p><p>Thanks again for the discussion.</p><p>Best regards,</p></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, Jun 2, 2025 at 8:51 AM Viktor Klang <<a href="mailto:viktor.klang@oracle.com">viktor.klang@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="msg-6626157483800923158">




<div dir="ltr">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
>My perspective is that strict adherence to input order for <code>mapConcurrent()</code> might not be the most common or beneficial default behavior for users.</div>
<div id="m_-6626157483800923158Signature">
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
If there is indeed a <b>majority</b> who would benefit from an unordered version of mapConcurrent (my experience is that the majority prefer ordered) then, since it is possible to implement such a Gatherer outside of the JDK, this is something which will be
 constructed, widely used, and someone will then propose to add something similar to the JDK.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
>While re-implementing the gatherer is a possibility, the existing implementation is non-trivial, and creating a custom, robust alternative represents a significant undertaking.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
The existing version needs to maintain order, which adds to the complexity of the implementation. Implementing an unordered version would likely look different.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
I'd definitely encourage taking the opportunity to attempt to implement it.</div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Cheers,<br>
√</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b><br>
</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b>Viktor Klang</b></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="m_-6626157483800923158appendonsend"></div>
<div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<hr style="display:inline-block;width:98%">
<div id="m_-6626157483800923158divRplyFwdMsg">
<div style="direction:ltr;font-family:Calibri,sans-serif;font-size:11pt;color:rgb(0,0,0)">
<b>From:</b> Jige Yu <<a href="mailto:yujige@gmail.com" target="_blank">yujige@gmail.com</a>><br>
<b>Sent:</b> Monday, 2 June 2025 17:05<br>
<b>To:</b> Viktor Klang <<a href="mailto:viktor.klang@oracle.com" target="_blank">viktor.klang@oracle.com</a>><br>
<b>Cc:</b> <a href="mailto:core-libs-dev@openjdk.org" target="_blank">core-libs-dev@openjdk.org</a> <<a href="mailto:core-libs-dev@openjdk.org" target="_blank">core-libs-dev@openjdk.org</a>><br>
<b>Subject:</b> Re: [External] : Re: Should mapConcurrent() respect time order instead of input order?</div>
<div style="direction:ltr"> </div>
</div>
<p style="direction:ltr">Thank you for your response and for considering my feedback on the
<code>mapConcurrent()</code> gatherer. I understand and respect that the final decision rests with the JDK maintainers.</p>
<p style="direction:ltr">I would like to offer a couple of further points for consideration. My perspective is that strict adherence to input order for
<code>mapConcurrent()</code> might not be the most common or beneficial default behavior for users. I'd be very interested to see any research or data that suggests otherwise, as that would certainly inform my understanding.</p>
<p style="direction:ltr">From my experience, a more common need is for higher throughput in I/O-intensive operations. The ability to support use cases like
<code>race()</code>—where the first successfully completed operation determines the outcome—also seems like a valuable capability that is currently infeasible due to the ordering constraint.</p>
<p style="direction:ltr">As I see it, if a developer specifically requires the input order to be preserved, this can be achieved with relative ease by applying a subsequent sorting operation. For instance:</p>
<pre><div style="direction:ltr"><code>.gather(mapConcurrent(...))
.sorted(Comparator.comparing(Result::getInputSequenceId))
</code></div></pre>
<p style="direction:ltr">The primary challenge in these scenarios is typically the efficient fan-out and execution of concurrent tasks, not the subsequent sorting of results.</p>
<p style="direction:ltr">Conversely, as you've noted, there isn't a straightforward way to modify the current default ordered behavior to achieve the higher throughput or
<code>race()</code> semantics that an unordered approach would naturally provide.</p>
<p style="direction:ltr">While re-implementing the gatherer is a possibility, the existing implementation is non-trivial, and creating a custom, robust alternative represents a significant undertaking. My hope was that an unordered
 option could be a valuable addition to the standard library, benefiting a wider range of developers.</p>
<p style="direction:ltr">Thank you again for your time and consideration.</p>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">On Mon, Jun 2, 2025 at 7:48 AM Viktor Klang <<a href="mailto:viktor.klang@oracle.com" id="m_-6626157483800923158OWA0b10cd62-e15d-cced-d6ae-02f98dafb304" target="_blank">viktor.klang@oracle.com</a>> wrote:</div>
<blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left:1px solid rgb(204,204,204)">
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
>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?</div>
<div id="m_-6626157483800923158x_m_4397928128062799969Signature">
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
The Gatherer doesn't know whether the Stream is unordered or ordered. The operation should be semantically equivalent anyway.</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Cheers,<br>
√</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b><br>
</b></div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b>Viktor Klang</b></div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="m_-6626157483800923158x_m_4397928128062799969appendonsend"></div>
<hr style="direction:ltr;display:inline-block;width:98%">
<div id="m_-6626157483800923158x_m_4397928128062799969divRplyFwdMsg">
<div style="direction:ltr;font-family:Calibri,sans-serif;font-size:11pt;color:rgb(0,0,0)">
<b>From:</b> Jige Yu <<a href="mailto:yujige@gmail.com" id="m_-6626157483800923158OWAdc362ec2-76bf-02b5-a482-ef2bb832f05d" target="_blank">yujige@gmail.com</a>><br>
<b>Sent:</b> Monday, 2 June 2025 16:29<br>
<b>To:</b> Viktor Klang <<a href="mailto:viktor.klang@oracle.com" id="m_-6626157483800923158OWA3c13ec0f-3f17-00dc-7de7-fe30cd251e54" target="_blank">viktor.klang@oracle.com</a>>;
<a href="mailto:core-libs-dev@openjdk.org" id="m_-6626157483800923158OWA7c83980e-d2cd-1590-4004-dc81b9208f13" target="_blank">
core-libs-dev@openjdk.org</a> <<a href="mailto:core-libs-dev@openjdk.org" id="m_-6626157483800923158OWAd51db75c-cd33-c326-694e-d3d93ff005d7" target="_blank">core-libs-dev@openjdk.org</a>><br>
<b>Subject:</b> [External] : Re: Should mapConcurrent() respect time order instead of input order?</div>
<div style="direction:ltr"> </div>
</div>
<div style="direction:ltr">Sorry. Forgot to copy to the mailing list.</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">On Mon, Jun 2, 2025 at 7:27 AM Jige Yu <<a href="mailto:yujige@gmail.com" id="m_-6626157483800923158OWA64dca995-5a04-057b-bad2-a4607638613a" target="_blank">yujige@gmail.com</a>> wrote:</div>
<blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left:1px solid rgb(204,204,204)">
<div style="direction:ltr">Thanks Viktor!</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">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. </div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">And I think wanting high throughput with real-life utilities like race would be more commonly useful.</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">But I could be wrong. </div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">Regardless, mapConcurrent() can do both, no? </div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">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?</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">On Mon, Jun 2, 2025 at 2:33 AM Viktor Klang <<a href="mailto:viktor.klang@oracle.com" id="m_-6626157483800923158OWAfbd2a49e-1eef-def3-9a2e-b61151d5db51" target="_blank">viktor.klang@oracle.com</a>> wrote:</div>
<blockquote style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left:1px solid rgb(204,204,204)">
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Hi!</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
In a similar vein to the built-in Collectors,</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
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.</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
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.</div>
<div id="m_-6626157483800923158x_m_4397928128062799969x_m_-1609416137456101297m_-5453718620750210517Signature">
<div style="direction:ltr;font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Cheers,<br>
√</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b><br>
</b></div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<b>Viktor Klang</b></div>
<div style="direction:ltr;font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
Software Architect, Java Platform Group<br>
Oracle</div>
</div>
<div id="m_-6626157483800923158x_m_4397928128062799969x_m_-1609416137456101297m_-5453718620750210517appendonsend">
</div>
<hr style="direction:ltr;display:inline-block;width:98%">
<div id="m_-6626157483800923158x_m_4397928128062799969x_m_-1609416137456101297m_-5453718620750210517divRplyFwdMsg">
<div style="direction:ltr;font-family:Calibri,sans-serif;font-size:11pt;color:rgb(0,0,0)">
<b>From:</b> core-libs-dev <<a href="mailto:core-libs-dev-retn@openjdk.org" id="m_-6626157483800923158OWA71ba725e-75dc-2a0f-f056-98efee8a74ec" target="_blank">core-libs-dev-retn@openjdk.org</a>> on behalf of Jige Yu <<a href="mailto:yujige@gmail.com" id="m_-6626157483800923158OWA1547d53c-f457-4e35-33ae-e9dac64fd65a" target="_blank">yujige@gmail.com</a>><br>
<b>Sent:</b> Sunday, 1 June 2025 21:08<br>
<b>To:</b> <a href="mailto:core-libs-dev@openjdk.org" id="m_-6626157483800923158OWAad0905c8-f06e-dab3-082c-585c489074ec" target="_blank">
core-libs-dev@openjdk.org</a> <<a href="mailto:core-libs-dev@openjdk.org" id="m_-6626157483800923158OWAa06657ff-fd5d-c3ab-908b-966d75adeafc" target="_blank">core-libs-dev@openjdk.org</a>><br>
<b>Subject:</b> Should mapConcurrent() respect time order instead of input order?</div>
<div style="direction:ltr"> </div>
</div>
<div style="direction:ltr">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.</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">If mapConcurrent() just respect output encounter order:</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">It'll be able to achieve <b>higher throughput</b> 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.</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">mapConcurrent() can be used to implement useful concurrent semantics, for example to
<b>support race</b> semantics. Imagine if I need to send request to 10 candidate backends and take whichever that succeeds first, I'd be able to do:</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">backends.stream()</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">    .gather(mapConcurrent(</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">        backend -> {</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">          try {</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">            return backend.fetchOrder();</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">           } catch (RpcException e) {</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">             return null; // failed to fetch but not fatal</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">           }</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">        })</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">        .filter(Objects::notNull)</div>
<div style="direction:ltr;margin-right:0px;margin-left:40px">        .findFirst(); // first success then cancel the rest</div>
<div style="direction:ltr"><br>
</div>
<div style="direction:ltr">Cheers,</div>
<div style="direction:ltr"><br>
</div>
</blockquote>
</blockquote>
</blockquote>
</div>

</div></blockquote></div>