RFR: 8334328: Reduce object allocation for FloatToDecimal and DoubleToDecimal
Shaojin Wen
duke at openjdk.org
Sat Jun 15 02:36:11 UTC 2024
On Sat, 15 Jun 2024 01:59:42 GMT, Shaojin Wen <duke at openjdk.org> wrote:
> The current versions of FloatToDecimal and DoubleToDecimal allocate additional objects. Reducing these allocations can improve the performance of Float/Double.toString and AbstractStringBuilder's append(float/double).
>
> This patch is just a code refactoring to reduce object allocation, but does not change the Float/Double to decimal algorithm.
>
> The following code comments the allocated objects to be removed.
>
>
> class FloatToDecimal {
> public static String toString(float v) {
> // allocate object FloatToDecimal
> return new FloatToDecimal().toDecimalString(v);
> }
>
> public static Appendable appendTo(float v, Appendable app)
> throws IOException {
> // allocate object FloatToDecimal
> return new FloatToDecimal().appendDecimalTo(v, app);
> }
>
> private Appendable appendDecimalTo(float v, Appendable app)
> throws IOException {
> switch (toDecimal(v)) {
> case NON_SPECIAL:
> // allocate object char[]
> char[] chars = new char[index + 1];
> for (int i = 0; i < chars.length; ++i) {
> chars[i] = (char) bytes[i];
> }
> if (app instanceof StringBuilder builder) {
> return builder.append(chars);
> }
> if (app instanceof StringBuffer buffer) {
> return buffer.append(chars);
> }
> for (char c : chars) {
> app.append(c);
> }
> return app;
> // ...
> }
> }
> }
>
> class DoubleToDecimal {
> public static String toString(double v) {
> // allocate object DoubleToDecimal
> return new DoubleToDecimal(false).toDecimalString(v);
> }
>
> public static Appendable appendTo(double v, Appendable app)
> throws IOException {
> // allocate object DoubleToDecimal
> return new DoubleToDecimal(false).appendDecimalTo(v, app);
> }
>
> private Appendable appendDecimalTo(double v, Appendable app)
> throws IOException {
> switch (toDecimal(v, null)) {
> case NON_SPECIAL:
> // allocate object char[]
> char[] chars = new char[index + 1];
> for (int i = 0; i < chars.length; ++i) {
> chars[i] = (char) bytes[i];
> }
> if (app instanceof StringBuilder builder) {
> return builder.append(chars);
> }
> ...
The performance numbers under `MacBookPro M1 Pro` & `MacBookPro 2018 i9` are as follows:
## Apple MacBookPro 2018
* CPU Intel i9 (x64)
-Benchmark Mode Cnt Score Error Units
-StringBuilders.appendWithFloat8Latin1 avgt 15 381.206 ? 8.681 ns/op
-StringBuilders.appendWithFloat8Utf16 avgt 15 366.549 ? 1.775 ns/op
-StringBuilders.appendWithDouble8Latin1 avgt 15 570.085 ? 8.040 ns/op
-StringBuilders.appendWithDouble8Utf16 avgt 15 501.409 ? 5.750 ns/op
+Benchmark Mode Cnt Score Error Units (Webrevs 00 4c810154)
+StringBuilders.appendWithFloat8Latin1 avgt 15 226.236 ? 3.350 ns/op +68.49%
+StringBuilders.appendWithFloat8Utf16 avgt 15 299.072 ? 19.895 ns/op +22.56%
+StringBuilders.appendWithDouble8Latin1 avgt 15 328.887 ? 5.865 ns/op +73.33%
+StringBuilders.appendWithDouble8Utf16 avgt 15 390.618 ? 30.142 ns/op +28.36%
## MacBook M1 Pro
* CPU Apple M1 Pro (aarch64)
-Benchmark Mode Cnt Score Error Units base
-StringBuilders.appendWithFloat8Latin1 avgt 15 317.144 ? 11.325 ns/op
-StringBuilders.appendWithFloat8Utf16 avgt 15 316.980 ? 17.955 ns/op
-StringBuilders.appendWithDouble8Latin1 avgt 15 440.853 ? 13.067 ns/op
-StringBuilders.appendWithDouble8Utf16 avgt 15 418.896 ? 4.610 ns/op
+Benchmark Mode Cnt Score Error Units (Webrevs 00 4c810154)
+StringBuilders.appendWithFloat8Latin1 avgt 15 168.231 ? 4.749 ns/op +88.51%
+StringBuilders.appendWithFloat8Utf16 avgt 15 213.981 ? 3.274 ns/op +48.13%
+StringBuilders.appendWithDouble8Latin1 avgt 15 241.536 ? 0.993 ns/op +82.52%
+StringBuilders.appendWithDouble8Utf16 avgt 15 284.863 ? 10.381 ns/op +47.05%
-------------
PR Comment: https://git.openjdk.org/jdk/pull/19730#issuecomment-2169061500
More information about the core-libs-dev
mailing list