<div dir="auto">+1 to option A.</div><div dir="auto"><br></div><div dir="auto">Option C is too limiting on uses for the target. It could be added as a default which calls through to option A, if there is meaningful demand.</div><div dir="auto"><br></div><div dir="auto">Is it a follow up change/PR for various places which would benefit from using the new method?</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 25, 2024 at 1:34 PM Markus Karg <<a href="mailto:markus@headcrashing.eu">markus@headcrashing.eu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="DE" link="blue" vlink="purple"><div class="m_-4781594925981999917WordSection1"><p class="MsoNormal">I hereby request for comments on the proposal to generalize the existing method "String.getChars()"'s signature to become a new default interface method "CharSequence.getChars()".<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Problem<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">For performance reasons, many CharSequence implementations, in particular String, StringBuilder, StringBuffer and CharBuffer, provide a way to bulk-read a complete region of their characters content into a provided char array.<u></u><u></u></p><p class="MsoNormal">Unfortunately, there is no _uniform_ way to perform this, and it is not guaranteed that there is bulk-reading implemented with _any_ CharSequence, in particular custom ones.<u></u><u></u></p><p class="MsoNormal">While String, StringBuilder and StringBuffer all share the same getChars() method signature for this purpose, CharBuffer's way to perform the very same is the get() method.<u></u><u></u></p><p class="MsoNormal">Other implementations have other method signatures, or do not have any solution to this problem at all.<u></u><u></u></p><p class="MsoNormal">In particular, there is no method in their common interface, CharSequence, to perform such an bulk-optimized read, as CharSequence only allows to read one character after the next in a sequential way, either by iterating over charAt() from 0 to length(), or by consuming the chars() Stream.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">As a result, code that wants to read from CharSequence in an implementation-agnostic, but still bulk-optimized way, needs to know _each_ possible implementation's specific method!<u></u><u></u></p><p class="MsoNormal">Effectively this results in code like this (real-world example taken from the implementation of Reader.of(CharSequence) in JDK 24):<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">switch (cs) {<u></u><u></u></p><p class="MsoNormal">               case String s -> s.getChars(next, next + n, cbuf, off);<u></u><u></u></p><p class="MsoNormal">               case StringBuilder sb -> sb.getChars(next, next + n, cbuf, off);<u></u><u></u></p><p class="MsoNormal">               case StringBuffer sb -> sb.getChars(next, next + n, cbuf, off);<u></u><u></u></p><p class="MsoNormal">               case CharBuffer cb -> cb.get(next, cbuf, off, n);<u></u><u></u></p><p class="MsoNormal">               default -> {<u></u><u></u></p><p class="MsoNormal">                              for (int i = 0; i < n; i++)<u></u><u></u></p><p class="MsoNormal">                                             cbuf[off + i] = cs.charAt(next + i);<u></u><u></u></p><p class="MsoNormal">               }<u></u><u></u></p><p class="MsoNormal">}<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">The problem with this code is that it is bound and limited to exactly that given set of CharSequence implementations.<u></u><u></u></p><p class="MsoNormal">If a future CharSequence implementation shall get accessed in an bulk-optimized way, the switch expression has to get extended and recompiled _every time_.<u></u><u></u></p><p class="MsoNormal">If some custom CharSequence implementation is used that this code is not aware of, sequential read is applied, even if that implementation _does_ provide some bulk-read method!<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Solution<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">There are several possible alternative solutions:<u></u><u></u></p><p class="MsoNormal">* (A) CharSequence.getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) - As this signature is already supported by String, StringBuffer and StringBuilder, I hereby propose to add this signature to CharSequence and provide a default implementation that iterates over charAt(int) from 0 to length().<u></u><u></u></p><p class="MsoNormal">* (B) Alternatively the same default method could be implemented using the chars() Stream - I assume that might run slower, but correct me if I am wrong.<u></u><u></u></p><p class="MsoNormal">* (C) Alternatively we could go with the signature get(char[] dst, int offset, int length) - Only CharBuffer implements that already, so more changes are needed and more duplicate methods will exist in the end.<u></u><u></u></p><p class="MsoNormal">* (D) Alternatively we could come up with a totally different signature - That would be most fair to all existing implementations, but in the end it will imply the most changes and the most duplicate methods.<u></u><u></u></p><p class="MsoNormal">* (E) We could give up the idea and live with the situation as-is. - I assume only few people really prefer that outcome.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Please tell me if I missed a viable option!<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">As a side benefit of CharSequence.getChars(), its existence might trigger implementors to provide bulk-reading if not done yet, at least for those cases where it is actually feasible.<u></u><u></u></p><p class="MsoNormal">In the same way it might trigger callers of Reader to start making use of bulk reading, at least in those cases where it does make sense but application authors were reluctant to implement the switch-case shown above.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Hence, if nobody vetoes, I will file Jira Issue, PR and CSR for "CharSequence.getChars()" (alternative A) in the next days.</p></div></div><div lang="DE" link="blue" vlink="purple"><div class="m_-4781594925981999917WordSection1"><p class="MsoNormal"><u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">-Markus<u></u><u></u></p></div></div></blockquote></div></div>