FasterXML / FasterXML/jackson-core

No-allocation DoubleToDecimal / FloatToDecimal

Đang mở
#1,652 10 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Java
Star
2.4k
Fork
928
Merge trung bình
2 ngày 18 giờ
Pull request đã merge (30 ngày)
24

Mô tả

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.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.