Bad performance in Writer.append(CharSequence)
Rob Spoor
openjdk at icemanx.nl
Sat Jul 27 10:44:23 UTC 2019
Hi,
I noticed the performance of Writer.append(CharSequence) (and its
indexed version) can be quite bad (especially with large CharSequences),
because they create a new String each time. I think that could be prevented.
Consider appending a StringBuilder or StringBuffer.
Writer.append(CharSequence, int, int) calls csq.subSequence(start, end).
That creates a new String, which copies part of the backing array.
Writer.append(CharSequence) on the other hand calls String.valueOf(csq),
which also creates a nwe String, which copies the entire backing array.
The String is then passed to Writer.write(String), which delegates to
Writer.write(String, int, int), which calls String.getChars. However,
StringBuilder and StringBuffer each have their own getChars method. It
would be more efficient to skip the intermediate String, and directly
call the StringBuilder / StringBuffer getChars method.
This leaves us with a few possibilities:
1) Have special cases in the Writer.append methods that check for
StringBuilder / StringBuffer; checking for AbstractStringBuilder isn't
possible because that's package private.
2) Add getChars as a default method to CharSequence. It would perform
the index checks and use length() and charAt(int) in the default
implementation; String, StringBuilder and StringBuffer automatically
provide better implementations.
In the second case, Writer.append(CharSequence, int, int) would then
look like Writer.write(String, int, int). Writer.append(CharSequence)
could simply do the following:
public Writer append(CharSequence csq) throws IOException {
if (csq == null) csq = "null";
return append(csq, 0, csq.length);
}
Any thoughts?
Kind regards,
Rob
More information about the core-libs-dev
mailing list