FasterXML / FasterXML/jackson-core

Can UTF8StreamJsonParser#finishString be made faster with VarHandles?

Open
#929 9 comments 0 reactions 0 assignees View on GitHub
3.x
Dominant language
Java
Stars
2.4k
Forks
928
Avg merge
2d 11h
Merged PRs (30d)
28

Description

I was looking at `UTF8StreamJsonParser#finishString` which seems to mostly consist of scanning for a trailing quote, with an optimized code path for ASCII strings. This optimized code path for ASCII strings could be further optimized by using VarHandles to compare multiple bytes at once.

The current code looks like this:

```java
while (ptr < max) {
int c = (int) inputBuffer[ptr] & 0xFF;
if (codes[c] != 0) {
if (c == INT_QUOTE) {
_inputPtr = ptr+1;
_textBuffer.setCurrentLength(outPtr);
return;
}
break;
}
++ptr;
outBuf[outPtr++] = (char) c;
}
```

and could become something like:

```java
private static final VarHandle VH_LE_LONG =
MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.LITTLE_ENDIAN);

[...]

while (ptr <= max - Long.BYTES) {
long next8Bytes = VH_LE_LONG.get(inputBuffer, ptr);
if ((next8Bytes & 0x8080808080808080L) != 0) {
// At least one of the bytes has the higher bit set, this is not a pure ASCII string
break;
}
if (hasValue(next8Bytes, INT_QUOTE)) { // Implement hasValue based on https://graphics.stanford.edu/~seander/bithacks.html#ValueInWord
// one of the next 8 bytes is a quote
break;
}
// Maybe this loop can become unnecessary via https://github.com/FasterXML/jackson-core/issues/910
for (int i = 0; i < Long.BYTES; ++i) {
outBuf[outPtr + i] = (char) inputBuffer[ptr + i];
}
ptr += Long.BYTES;
outPtr += Long.BYTES;
}
while (ptr < max) {
int c = (int) inputBuffer[ptr] & 0xFF;
if (codes[c] != 0) {
if (c == INT_QUOTE) {
_inputPtr = ptr+1;
_textBuffer.setCurrentLength(outPtr);
return;
}
break;
}
++ptr;
outBuf[outPtr++] = (char) c;
}
```

As VarHandles were introduced in Java 9, this would require releasing a MR JAR or bumping the min required version.

I haven't had a chance to measure if it made a significant difference but wanted to log the idea in case it gets someone's attention.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.