david-mollitor-db opened a new pull request, #59198:
URL: https://github.com/apache/spark/pull/59198

   ### What changes were proposed in this pull request?
   
   `UTF8String.toLowerCase()` / `toUpperCase()` dispatch to the ASCII fast paths
   `toLowerCaseAscii()` / `toUpperCaseAscii()` once `isFullAscii()` holds. This 
PR rewrites
   those fast paths:
   
   - Convert bytes with direct ASCII arithmetic (`A`-`Z` <-> `a`-`z` by +/- 32) 
instead of
     routing each byte through an autoboxed `Function<Character, Character>` and
     `Character.toLowerCase`/`toUpperCase` (a full Unicode-table lookup). Over 
ASCII code
     points the two are identical.
   - Allocate the result array lazily, only when a byte actually changes case, 
bulk-copying
     the unchanged prefix with `Platform.copyMemory`. A string already in the 
target case
     returns `this` with no allocation.
   - Tag the converted result as full ASCII (`IsFullAscii.FULL_ASCII`), since 
ASCII case
     folding stays ASCII, so downstream operations skip re-scanning for 
ASCII-ness.
   - Remove the now-unused `convertAscii` helper and its 
`java.util.function.Function` import,
     and add an `assert isFullAscii()` precondition to both methods (callers 
already gate on
     `isFullAscii()`).
   
   Also adds `UTF8StringBenchmark` exercising `toLowerCase`/`toUpperCase` over 
all-lowercase,
   all-uppercase, and mixed-case ASCII inputs.
   
   NOTE (WIP): the benchmark result file is not yet committed; it will be 
regenerated on
   GitHub Actions for a consistent environment.
   
   ### Why are the changes needed?
   
   `toLowerCase`/`toUpperCase` back the SQL `lower()`/`upper()` functions and 
are hot in
   predicates such as `lower(col) LIKE '%...%'`. The previous fast path always 
allocated a new
   array and `UTF8String` and did per-byte autoboxing plus a Unicode 
case-mapping lookup, even
   though the string was already known to be ASCII. For strings already in the 
target case this
   is pure overhead; when conversion is needed, the Unicode lookup is 
unnecessary for ASCII.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. Results are unchanged for every input. One internal nuance: on the 
no-change path the
   returned value now aliases the input's backing memory rather than being a 
fresh copy, which
   is consistent with `UTF8String`'s existing immutability / copy-on-retain 
contract.
   
   ### How was this patch tested?
   
   Covered by existing `UTF8StringSuite` assertions for 
`toLowerCase`/`toUpperCase`, including
   the already-cased cases that exercise the new return-`this` path.
   
   Added `UTF8StringBenchmark`. Preliminary local numbers (JDK 17, indicative 
only; the
   committed result file will be regenerated on GitHub Actions per the PR 
template,
   https://spark.apache.org/developer-tools.html#github-workflow-benchmarks), 
best-time ns/row
   over 16000 strings of 64 ASCII chars, master vs. this PR:
   
   | operation | input | master (ns/row) | this PR (ns/row) | speedup |
   |---|---|---|---|---|
   | toLowerCase | all lowercase (no-change fast path) | 101.9 | 71.7 | 1.42x |
   | toLowerCase | all uppercase (full convert) | 126.7 | 113.6 | 1.12x |
   | toLowerCase | mixed case | 413.0 | 381.5 | 1.08x |
   | toUpperCase | all lowercase (full convert) | 143.7 | 113.6 | 1.26x |
   | toUpperCase | all uppercase (no-change fast path) | 124.6 | 71.1 | 1.75x |
   | toUpperCase | mixed case | 459.3 | 370.6 | 1.24x |
   
   The largest gain is on already-cased inputs, which return `this` with no 
allocation; the
   conversion path is faster too from dropping the per-byte boxing and Unicode 
lookup. Fixed
   harness overhead (the benchmark passes the operation as a function, which 
blocks inlining)
   dilutes the relative numbers, so the per-call improvement is larger than 
shown.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Isaac
   
   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]

Reply via email to