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

Reply via email to