Optimize parsing 19 digit longs by marschall · Pull Request #865 · FasterXML/jackson-core (original) (raw)
Parsing 19 digit long values is significantly slower than parsing 18 digit long values as we are hitting a slow path that does a string allocation.
19 digit long values are quite common when a random number generator is used to generate long values.
We have to pay attention that we only use this fast path if the value is a valid long. This can be achieved by calling #inLongRange
first.
In the following synthetic microbenchmark a throughput increase of about 33% with a drastic reduction in the allocation rate can be achieved.
@OutputTimeUnit(TimeUnit.SECONDS) public class JacksonStdLongReadVanilla {
private static final JsonFactory JSON_FACTORY = new JsonFactory();
private static final String JSON;
static {
StringBuilder json = new StringBuilder();
Random random = new Random(0L);
json.append('[');
for (int i = 0; i < 1_000; i++) {
if (i > 0) {
json.append(',');
}
json.append(random.nextLong());
}
json.append(']');
JSON = json.toString();
}
@Benchmark
public void parseLong(Blackhole blackhole) throws IOException {
try (JsonParser parser = JSON_FACTORY.createParser(JSON)) {
parser.nextToken();
JsonToken nextToken = parser.nextToken();
while (nextToken == JsonToken.VALUE_NUMBER_INT) {
blackhole.consume(parser.getLongValue());
nextToken = parser.nextToken();
}
}
}
}
If we have a look at the allocations before we see that it is dominated by byte[]
allocations for String
allocations
Resulting in many gcs
With the changes in this PR the byte[]
and String
allocations are gone
Resulting in no more gcs