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