FasterXML / FasterXML/jackson-core

No-allocation DoubleToDecimal / FloatToDecimal

Ouverte
#1,652 10 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Java
Étoiles
2.4k
Forks
928
Merge moyen
2 j 18 h
PR mergées (30 j)
24

Description

OpenJDK25 added implementations of `DoubleToDecimal` and `FloatToDecimal` that encode directly to Latin1 bytes without any allocations: https://github.com/openjdk/jdk/commit/9d20b58f40275002afa0348d94d5592a26894e88

If this was public API, it could be used pretty easily within UTF8JsonGenerator for some fairly massive performance benefits when serializing large numbers of floating point numbers -- something that's very common with GeoJSON.
```java
@Override
public void writeNumber(double d) throws IOException {
if (this._outputTail + DoubleToDecimal.MAX_CHARS >= this._outputEnd) {
this._flushBuffer();
}
this._outputTail = DoubleToDecimal.LATIN1.putDecimal(this._outputBuffer, this._outputTail, d);
}
```

A simple benchmark that tests this change by writing a 10k element float/double array to a null output stream shows that this approach is nearly 3x as fast, even when the relevant internal utility is copied out of the JDK (removing the requirement of `--add-opens`).
```
Benchmark (type) (mode) Mode Cnt Score Error Units
WriteFloatingPointArray.write FLOAT VANILLA thrpt 4 1934.454 ± 84.062 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm FLOAT VANILLA thrpt 4 880296.792 ± 0.825 B/op
WriteFloatingPointArray.write FLOAT JACKSON_FAST thrpt 4 2116.445 ± 52.042 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm FLOAT JACKSON_FAST thrpt 4 880263.591 ± 248.715 B/op
WriteFloatingPointArray.write FLOAT JDK_INTERNAL thrpt 4 3708.587 ± 491.341 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm FLOAT JDK_INTERNAL thrpt 4 383.432 ± 12.262 B/op
WriteFloatingPointArray.write FLOAT JDK_COPY thrpt 4 3623.090 ± 240.293 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm FLOAT JDK_COPY thrpt 4 383.387 ± 13.224 B/op
WriteFloatingPointArray.write DOUBLE VANILLA thrpt 4 1268.260 ± 39.709 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm DOUBLE VANILLA thrpt 4 1040193.112 ± 0.036 B/op
WriteFloatingPointArray.write DOUBLE JACKSON_FAST thrpt 4 1532.169 ± 190.942 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm DOUBLE JACKSON_FAST thrpt 4 1040192.921 ± 0.115 B/op
WriteFloatingPointArray.write DOUBLE JDK_INTERNAL thrpt 4 2788.184 ± 497.046 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm DOUBLE JDK_INTERNAL thrpt 4 315.239 ± 35.377 B/op
WriteFloatingPointArray.write DOUBLE JDK_COPY thrpt 4 2704.880 ± 379.627 ops/s
WriteFloatingPointArray.write:gc.alloc.rate.norm DOUBLE JDK_COPY thrpt 4 315.170 ± 34.143 B/op
```

Based on these results it seems like it would be valuable to optimize Jackson's copy of `*ToDecimal` and bring back `USE_FAST_DOUBLE_WRITER` for modern JDKs? I'm not positive but I don't believe the JDK's implementation of these directly into jackson-core due to licensing, and I suspect relying on `--add-opens java.base/jdk.internal.math=ALL-UNNAMED` is not a good approach for a general purpose library.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.