look at uptaking some of the performance and fast-fail BigDecimal parser code from jsoniter-scala
pjfanning opened this issue · 5 comments
Maybe something for jackson v2.15. Idea is to enhance the existing BigDecimalParser class.
@plokhotnyuk suggested looking at https://github.com/plokhotnyuk/jsoniter-scala/blob/3b062f77f566d64b68b765ceed3738ad93d475dc/jsoniter-scala-core/native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonReader.scala#L1647-L1874
He provides some analysis at https://stackoverflow.com/a/58777171/228843
He provided some benchmarks at FasterXML/jackson-module-scala#572 (comment)
I have a prototype at https://github.com/pjfanning/jackson-number-parse-bench/blob/main/src/main/java/org/example/jackson/bench/FastBigDecimalParser.java
- it is a little faster than the existing parser
- it still needs more testing and some more error handling. It may be possible to get a little bit better perf from it.
- it still works by taking a full String or char[] with the number as opposed to working directly on the input data stream like the jsoniter-scala does - so it won't match jsoniter-scala performance.
I think it's fine to require copy as char[]
or String
; although I guess some parser backends could conceivably pass offsets to internal char[]
quite easily. But it does not seem like a humongous overhead regardless; at most it's good to maybe avoid throw-away String
instances (which I think is doable).
The current benchmark for FastBigDecimalParser suggests it is better for numbers with lots of digits (and still a little better for numbers with a small number of digits).
For BigInteger parsing, I got:
Benchmark Mode Cnt Score Error Units
BigIntegerParserBench.bigDec1000 thrpt 5 35195.566 ± 2758.478 ops/s
BigIntegerParserBench.bigDec10000 thrpt 5 1232.178 ± 221.485 ops/s
BigIntegerParserBench.bigDec1000000 thrpt 5 0.396 ± 0.031 ops/s
BigIntegerParserBench.bigInt1000 thrpt 5 48308.680 ± 671.193 ops/s
BigIntegerParserBench.bigInt10000 thrpt 5 617.721 ± 14.032 ops/s
BigIntegerParserBench.bigInt1000000 thrpt 5 0.063 ± 0.002 ops/s
BigIntegerParserBench.fastBigDec1000 thrpt 5 138409.766 ± 10781.948 ops/s
BigIntegerParserBench.fastBigDec1000000 thrpt 5 2.342 ± 0.019 ops/s
I'll close this as we have gone down the route of using https://github.com/wrandelshofer/FastDoubleParser
jsoniter-scala is actually faster but it parses the number as it streams the bytes/chars instead of building up strings and parsing those as numbers like Jackson does. Changing Jackson do this would be quite some refactor.
Agreed, FDP seems to work for now.