RFR: 8358533: Improve performance of java.io.Reader.readAllLines
Markus KARG
duke at openjdk.org
Thu Jun 19 11:18:07 UTC 2025
On Wed, 18 Jun 2025 00:04:37 GMT, Brian Burkhalter <bpb at openjdk.org> wrote:
> Replaces the implementation `readAllCharsAsString().lines().toList()` with reading into a temporary `char` array which is then processed to detect line terminators and copy non-terminating characters into strings which are added to the list.
src/java.base/share/classes/java/io/Reader.java line 480:
> 478: pos++;
> 479: } else { // term > pos
> 480: if (eol && sb.length() == 0) {
Is there a reason for `sb.length() == 0` instead of `sb.isEmpty()`?
src/java.base/share/classes/java/io/Reader.java line 508:
> 506: }
> 507:
> 508: return lines;
Do we really want to return a mutable `ArrayList` here? In earlier discussions about this very API I was told that it deliberately returns `String` instead of `CharSequence` due to *intended* immutability, even if that potentially implied slower performance. Following this logic, it would be just straightforward to `return Collections.unmodifiableList(lines);` here. 🤔
src/java.base/share/classes/java/io/Reader.java line 551:
> 549: public String readAllAsString() throws IOException {
> 550: StringBuilder result = new StringBuilder();
> 551: char[] cbuf = new char[TRANSFER_BUFFER_SIZE];
As this PR explicitly targets performance and as the aim of this method is to keep **all** content in-memory anyways, I wonder if it would be acceptable and even faster to pre-allocate `new StringBuilder(TRANSFER_BUFFER_SIZE)`? In the end, this allocation is just temporary.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/25863#discussion_r2156727346
PR Review Comment: https://git.openjdk.org/jdk/pull/25863#discussion_r2156742905
PR Review Comment: https://git.openjdk.org/jdk/pull/25863#discussion_r2156750703
More information about the core-libs-dev
mailing list