On Tue, 1 Jul 2025 02:33:16 GMT, Chen Liang <li...@openjdk.org> wrote:

> I think we can split this into two parts:
> 
> 1. Update buffering strategy for BufferedWriter when backing writer is an 
> OutputStreamWriter
> 2. Use an alternative StreamDecoder impl if the CharsetDecoder is an 
> ArrayDecoder
> 
> This should make the whole thing more clear.

You are right. The current PR is the fast path optimization of UTF_8 
OutputStreamWriter. For UTF_16/UTF_16LE/UTF_16BE, I submitted a draft pr 26034.

And for the buffer of BufferedWriter, if char[] is used, the encodeArrayLoop 
technique can be used in CharsetEncoder for optimization. If the buffer uses 
StringBuilder wrap as StringCharBuffer, StringCharBuffer cannot use 
encodeArrayLoop for optimization, which is the key point affecting performance.

| buffer type | CharBuffer type   | support arrayLoop |
| -- | -- | -- | 
| char[] | HeapCharBuffer | true |
| StringBuilder | StringCharBuffer | false |

Therefore, I recommend continuing to use char[] as buffer in BufferedWriter 
non-UTF_8 OutputStreamWriter scenarios.


If you are interested, you can take a look at the optimization of these two 
encodeArrayLoop:

* In UTF_8$Encoder

public final class UTF_8 extends Unicode {
    private static final class Encoder extends CharsetEncoder {
        protected final CoderResult encodeLoop(CharBuffer src,
                                               ByteBuffer dst)
        {
            if (src.hasArray() && dst.hasArray())
                return encodeArrayLoop(src, dst);
            else
                return encodeBufferLoop(src, dst);
        }
        // ...
        }
}


* UnicodeEncoder in PR #26034

public abstract class UnicodeEncoder extends CharsetEncoder {
  protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
        if (src.hasArray() && dst.hasArray()) {
            return encodeArrayLoop(src, dst);
        }
        return encodeBufferLoop(src, dst);
    }

    private CoderResult encodeArrayLoop(CharBuffer src, ByteBuffer dst) {
        char[] sa = src.array();
        int soff = src.arrayOffset();
        int sp = soff + src.position();
        int sl = soff + src.limit();

        byte[] da = dst.array();
        int doff = dst.arrayOffset();
        int dp = doff + dst.position();
        int dl = doff + dst.limit();

        ....
    }
}

-------------

PR Comment: https://git.openjdk.org/jdk/pull/26022#issuecomment-3022903336

Reply via email to