RFR: 8361018: Eliminate unnecessary buffering and encoding conversion in BufferedWriter

Shaojin Wen swen at openjdk.org
Mon Jun 30 04:54:50 UTC 2025


On Fri, 27 Jun 2025 16:48:40 GMT, Shaojin Wen <swen at openjdk.org> wrote:

> BufferedWriter -> OutputStreamWriter -> StreamEncoder
> 
> In this call chain, BufferedWriter has a char[] buffer, and StreamEncoder has a ByteBuffer. There are two layers of cache here, or the BufferedWriter layer can be removed. And when charset is UTF8, if the content of write(String) is LATIN1, a conversion from LATIN1 to UTF16 and then to LATIN1 will occur here.
> 
> LATIN1 -> UTF16 -> UTF8
> 
> We can improve BufferedWriter. When the parameter Writer instanceof OutputStreamWriter is passed in, remove the cache and call it directly. In addition, improve write(String) in StreamEncoder to avoid unnecessary encoding conversion.

Performance test data shows that this PR can significantly improve the performance of BufferedWriter, and can improve the performance by 30%~50% in the write(String) scenario.

## Benchmark Script

git remote add wenshao git at github.com:wenshao/jdk.git
git fetch wenshao

#baseline
git checkout 2758d6ad7767832db004d28f10cc764f33fa438e
make make test TEST="micro:java.io.BufferedWriterBench"

# current
git checkout 13fd490e75ed3ec4be1957e183ab1631c2029c05
make make test TEST="micro:java.io.BufferedWriterBench"


## Benchmark Numbers on MacBook M1 Pro (aarch64)

# baseline
-Benchmark                             (charType)  (charset)  Mode  Cnt   Score   Error  Units
-BufferedWriterBench.writeCharArray         ascii       UTF8  avgt   12   2.672 ± 0.097  us/op
-BufferedWriterBench.writeCharArray  utf8_2_bytes       UTF8  avgt   12  22.310 ± 0.150  us/op
-BufferedWriterBench.writeCharArray  utf8_3_bytes       UTF8  avgt   12  21.442 ± 0.097  us/op
-BufferedWriterBench.writeCharArray         emoji       UTF8  avgt   12  34.750 ± 0.245  us/op
-BufferedWriterBench.writeString            ascii       UTF8  avgt   12   2.831 ± 0.078  us/op
-BufferedWriterBench.writeString     utf8_2_bytes       UTF8  avgt   12  22.200 ± 0.102  us/op
-BufferedWriterBench.writeString     utf8_3_bytes       UTF8  avgt   12  21.522 ± 0.132  us/op
-BufferedWriterBench.writeString            emoji       UTF8  avgt   12  34.973 ± 0.331  us/op

# current
+Benchmark                             (charType)  (charset)  Mode  Cnt   Score   Error  Units
+BufferedWriterBench.writeCharArray         ascii       UTF8  avgt   12   2.663 ± 0.077  us/op +0.33%
+BufferedWriterBench.writeCharArray  utf8_2_bytes       UTF8  avgt   12  13.807 ± 0.080  us/op +61.58%
+BufferedWriterBench.writeCharArray  utf8_3_bytes       UTF8  avgt   12  16.157 ± 0.230  us/op +32.71%
+BufferedWriterBench.writeCharArray         emoji       UTF8  avgt   12  21.891 ± 0.158  us/op +58.74%
+BufferedWriterBench.writeString            ascii       UTF8  avgt   12   2.125 ± 0.190  us/op +33.22%
+BufferedWriterBench.writeString     utf8_2_bytes       UTF8  avgt   12  14.260 ± 0.716  us/op +55.68%
+BufferedWriterBench.writeString     utf8_3_bytes       UTF8  avgt   12  12.587 ± 0.099  us/op +70.98%
+BufferedWriterBench.writeString            emoji       UTF8  avgt   12  22.810 ± 0.168  us/op +53.32%

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

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


More information about the nio-dev mailing list