RFR: 8361018: Re-examine buffering and encoding conversion in BufferedWriter [v6]
Shaojin Wen
swen at openjdk.org
Tue Jul 1 09:20:43 UTC 2025
On Tue, 1 Jul 2025 02:33:16 GMT, Chen Liang <liach at 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
More information about the nio-dev
mailing list