david-mollitor-db opened a new pull request, #59224:
URL: https://github.com/apache/spark/pull/59224
### What changes were proposed in this pull request?
This adds a private `UTF8String.getByteUnchecked(int)` that reads a byte
without `getByte`'s range check, and uses it at the internal call sites whose
loop already keeps the index in range.
- The public `getByte` keeps its range check, still returns 0 for an
out-of-range index, and now calls `getByteUnchecked` for the read itself.
`getByteUnchecked` has no check of its own, not even an `assert`: an `assert`
makes it 41 bytes of bytecode, over the JIT's 35-byte `MaxInlineSize`, and the
JIT then sometimes left it as a real call (`callee is too large`) in loops such
as `getIsValid`.
- 45 internal call sites switch to `getByteUnchecked`. Each one's loop
condition, or a check just before it, proves `0 <= index < numBytes`. They are
in `numChars`, `isValid` / `makeValid`, `isFullAscii`, the code point
iterators, `substring`, `codePointFrom`, ASCII case conversion, `findInSet`,
`trim` / `trimAll` / `trimLeft` / `trimRight` (with and without a trim string),
`reverse`, `indexOf`, `charPosToByte` / `bytePosToChar`, `toInt` / `toLong` and
`soundex`.
- 11 call sites stay on `getByte`, because they can index past the end or
their range depends on an invariant outside the loop:
- `contains`, which #59222 (SPARK-59967) replaces
- `getChar`, whose walk is bounded by the cached `numChars` rather than by
`numBytes`
- `trimTrailingSpaces`, whose loop bound `numBytes - numSpaces` can be
negative
- `prevCharStart`, whose range depends on its callers
- the read after a match in `indexOf(pattern, start, occurrence)`, which
can run past the end when a truncated multi-byte sequence ends the string
- the walks in `levenshteinDistance`, which are bounded by character
counts, and one of which reads one character past the end
### Why are the changes needed?
These loops back common string functions and casts (`length`, `substring`,
`trim`, `instr` / `locate`, `CAST(string AS INT/BIGINT)`, case conversion,
UTF-8 validation). The range check costs a compare and a branch on every byte
read. The JIT can't always remove it, especially in character walks, where each
step advances by the width of the current character.
Local JMH results (JDK 17, ns per call, ~128-byte rows; a fresh `UTF8String`
per call so cached `numChars` / `isValid` / `isFullAscii` don't skip the scan):
_Results table to follow: a final interleaved before/after run is in
progress._
### Does this PR introduce _any_ user-facing change?
No. Only performance changes; the public `getByte` behaves the same.
### How was this patch tested?
- New `UTF8StringSuite.internalByteReadsOnEdgeCaseInputs` runs every method
that uses `getByteUnchecked` on empty, all-whitespace, sign-only, and truncated
or invalid multi-byte inputs, both on heap at a non-zero offset and off heap.
It checks the results for the trim methods and for `toInt` / `toLong` on
whitespace and lone signs.
- Each converted call site was checked by hand: its loop condition, or a
check just before it, keeps the index in `[0, numBytes)`. During development,
`getByteUnchecked` temporarily asserted its index, and this test failed when
the read after a match in `indexOf(pattern, start, occurrence)` was switched
over. That is why that read stays on `getByte`.
- Existing `UTF8StringSuite`, `UTF8StringPropertyCheckSuite`,
`ByteArraySuite`, `CollationSupportSuite` and `CollationFactorySuite` pass.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Isaac (Claude Code, Claude Opus 5.5)
This pull request and its description were written by Isaac.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]