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

   ### What changes were proposed in this pull request?
   
   Casting an integral (byte/short/int/long) or boolean value to string routed 
through
   `java.lang.String`: both the interpreted and codegen paths in `ToStringBase` 
emitted
   `UTF8String.fromString(String.valueOf(x))`, and 
`UTF8String.fromString(String)` does
   `str.getBytes(StandardCharsets.UTF_8)`. A single `CAST(<long> AS STRING)` 
therefore
   allocated a `java.lang.String`, its backing array, a re-encoded UTF-8 
`byte[]`, and the
   result `UTF8String` -- only the last two are essential.
   
   This PR adds two `UTF8String` factories and uses them in `ToStringBase`:
   
   - `UTF8String.fromLong(long)` writes the base-10 ASCII digits directly into 
a single
     `byte[]` (no intermediate `java.lang.String`).
   - `UTF8String.fromBoolean(boolean)` returns a shared cached 
`"true"`/`"false"` instance.
   
   The integral and boolean cases are added before the existing 
`String.valueOf` fallthrough in
   both `ToStringBase` conversion paths (interpreted `castToStringDefault` and 
codegen
   `castToStringCode`). byte/short/int widen to long without changing the 
decimal
   representation; `Float`/`Double` and all other types keep the current 
fallthrough.
   
   ### Why are the changes needed?
   
   `CAST(<integral> AS STRING)` is a very common expression (key building, 
string
   concatenation, display), and the `java.lang.String` round-trip is avoidable 
per-row
   overhead. JFR allocation profiling of `AggregateBenchmark`'s "aggregate with 
string key"
   case (keys built with `cast(id & 1023 as string)`) attributed the bulk of 
sampled
   allocation to the cast's String round-trip. With this change the 
`Long.toString` (~64%) and
   `Arrays.copyOf(byte[])` (~32%) allocation sites collapse to ~0, leaving only 
the irreducible
   result allocation (`UTF8String.fromBytes`). Per-row allocation for these 
casts drops from
   ~4 objects to one `byte[]` plus one `UTF8String`. Both `Cast` and 
`ToPrettyString` (which
   mix in `ToStringBase`) benefit.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. The output is byte-identical to `String.valueOf`/`Long.toString`.
   
   ### How was this patch tested?
   
   New `UTF8StringSuite` tests for `fromLong` (zero, sign and digit-count 
boundaries,
   `Integer`/`Long` MIN and MAX, values past int range, and a contiguous sweep 
compared with
   `String.valueOf`) and `fromBoolean`. Existing `CastWithAnsiOnSuite`, 
`CastWithAnsiOffSuite`,
   and `ToPrettyStringSuite` pass unchanged.
   
   ### 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