<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"Chen Liang" <chen.l.liang@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br><b>Cc: </b>"core-libs-dev" <core-libs-dev@openjdk.org><br><b>Sent: </b>Sunday, May 11, 2025 5:41:25 PM<br><b>Subject: </b>Re: Unnecessary logic is added to removeFirst and removeLast of ArrayList.<br></blockquote></div><div><style style="display:none;"> P {margin-top:0;margin-bottom:0;} </style></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
> where the generated assembly code by the JITs is checked by humans</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Is it? </div></blockquote><div><br></div><div><div>At least, it was true during the Java 8 timeframe :)</div><div>At that time, i was involved in the effort of updating the collection API to use lambdas.</div><div><br data-mce-bogus="1"></div><div>I suppose that the introduction of value types will trigger a similar effort (even if it seems less easier to use value types to optimize the collection API because the spec allows a lot of modifications).</div></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">I have heard anecdotes that it is still slower than direct array usage, presumably due to the modCount tracking mechanism. Don't know if escape analysis and the resulting stack allocation in the compiled code eliminates that field.</div></blockquote><div><br></div><div>I've recently bench array vs arraylist (while testing the performance of StableValue.list()),</div>for 1024 string ("0", "1", "2" etc), on my Mac M2 air, i get</div><div data-marker="__QUOTED_TEXT__"><div><br></div><div><div style="background-color: #ffffff; color: #080808;" data-mce-style="background-color: #ffffff; color: #080808;"><pre style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;" data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;"><strong><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// Benchmark Mode Cnt Score Error Units<br></span><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// StableListBench.array avgt 5 427,889 ± 1,553 ns/op<br></span><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// StableListBench.arraylist avgt 5 605,542 ± 1,372 ns/op<br></span><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// StableListBench.asList avgt 5 572,532 ± 2,574 ns/op<br></span><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// StableListBench.list_of avgt 5 615,069 ± 0,341 ns/op<br></span><span style="color: rgb(140, 140, 140);" data-mce-style="color: #8c8c8c;">// StableListBench.stable_list avgt 5 1897,948 ± 2,119 ns/op</span></strong></pre></div></div><div>with</div><div><div style="background-color: #ffffff; color: #080808;" data-mce-style="background-color: #ffffff; color: #080808;"><pre style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;" data-mce-style="font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;"><span style="color: #9e880d;" data-mce-style="color: #9e880d;">@Benchmark<br></span><span style="color: #0033b3;" data-mce-style="color: #0033b3;">public int </span><span style="color: #00627a;" data-mce-style="color: #00627a;">list_of</span>() {<br> <span style="color: #0033b3;" data-mce-style="color: #0033b3;">var </span><span style="color: #000000;" data-mce-style="color: #000000;">sum </span>= <span style="color: #1750eb;" data-mce-style="color: #1750eb;">0</span>;<br> <span style="color: #0033b3;" data-mce-style="color: #0033b3;">for</span>(<span style="color: #0033b3;" data-mce-style="color: #0033b3;">var </span><span style="color: #000000;" data-mce-style="color: #000000;">item </span>: <span style="color: #871094;" data-mce-style="color: #871094;">listof</span>) {<br> <span style="color: #000000;" data-mce-style="color: #000000;">sum </span>+= <span style="color: #000000;" data-mce-style="color: #000000;">item</span>.length();<br> }<br> <span style="color: #0033b3;" data-mce-style="color: #0033b3;">return </span><span style="color: #000000;" data-mce-style="color: #000000;">sum</span>;<br>}</pre></div></div><div><br></div><div>So at least, I can say that on my mac, direct array usage is more efficient. <br></div><div>(BTW, using an arraylist is more effcient than using List.of()/List.copyOf() because ListN inherits from the iterator of AbstractList instead of having its own).</div><div><br data-mce-bogus="1"></div><div>regards,</div><div>Rémi</div><div><br></div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div style="font-family: 'Calibri Light', 'Helvetica Light', sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: 'Calibri Light', 'Helvetica Light', sans-serif; font-size: 12pt; color: #000000;"><br></div><hr style="display: inline-block; width: 98%;" data-mce-style="display: inline-block; width: 98%;"><div id="divRplyFwdMsg" dir="ltr"><span style="font-family: Calibri, sans-serif; font-size: 11pt; color: #000000;" data-mce-style="font-family: Calibri, sans-serif; font-size: 11pt; color: #000000;"><b>From:</b> core-libs-dev <core-libs-dev-retn@openjdk.org> on behalf of Remi Forax <forax@univ-mlv.fr><br><b>Sent:</b> Sunday, May 11, 2025 5:16 AM<br><b>To:</b> 임민수 <godmlzkf1@naver.com><br><b>Cc:</b> core-libs-dev <core-libs-dev@openjdk.org><br><b>Subject:</b> Re: Unnecessary logic is added to removeFirst and removeLast of ArrayList.</span><div class="elementToProof"> </div></div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">Duplicating the logic is bad in some cases and not that bad in other cases.</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;"><br></div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">Here ArrayList is one of the most used class in Java (with String and HashMap), it is heavily optimized (to the point where the generated assembly code by the JITs is checked by humans), so duplicating the logic is not a bad idea,</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">From a documentation POV, you do not have to jump through many methods if you want to see the implementation and in terms of performance, you want the inlining to be done by hand because the methods of ArrayList are usually deep in the call graph, so you may reach the inlining threshold right inside removeFirst().</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;"><br></div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">In general, you do not optimize applications and libraries the same way.</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">Usually, you do not optimize application code that often but for a library, if a lot of people are using it, it may worth to spend time to optimize for the benefit of everybody.</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;"><br></div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">regards,</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;">Rémi</div><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;" data-mce-style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000;"><br></div><br></blockquote></div></div></body></html>