Skip to content

perf: return Utf8View from Spark hex with inline short path - #24494

Open
shinzoxD wants to merge 1 commit into
apache:mainfrom
shinzoxD:perf/spark-hex-utf8view
Open

perf: return Utf8View from Spark hex with inline short path#24494
shinzoxD wants to merge 1 commit into
apache:mainfrom
shinzoxD:perf/spark-hex-utf8view

Conversation

@shinzoxD

@shinzoxD shinzoxD commented Aug 19, 2026

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

Review of #15947 asked Spark hex to return Utf8View instead of Utf8, with a fast path for encodings that fit in the StringView inline prefix (12 bytes). The lookup table (#21836) and criterion benches (#19738) already landed. This finishes the remaining item on #15986.

Short hex results are common (small integers, short strings/binaries). Building a Utf8 StringArray for those rows pays for offset buffers and a data buffer even when Arrow can store the digits in the view itself. Returning Utf8View avoids that for encodings of at most 12 bytes and still stores longer encodings out-of-line.

What changes are included in this PR?

  • SparkHex::return_type is now Utf8View, including dictionary values (Dictionary(K, Utf8View)).
  • Encodings of at most 12 hex digits are inlined via make_view and never touch the StringView data buffer.
  • Longer encodings are written once into that buffer and referenced by offset.
  • Input null buffers are still reused (ptr_eq on the inner validity buffer).
  • BinaryView inputs are handled (the signature already accepted them).
  • Criterion bench adds hex_utf8_inline for the short-string path. I am not posting machine-local timings here; please run cargo bench -p datafusion-spark --bench hex against main if you want a comparison.

Are these changes tested?

Yes.

  • Unit tests in datafusion/spark/src/function/math/hex.rs cover Utf8View / LargeUtf8 / BinaryView inputs, null reuse, the 12- vs 13-digit inline boundary, and return_type.
  • SQL logic tests in datafusion/sqllogictest/test_files/spark/math/hex.slt assert values plus arrow_typeof(hex(...)) = Utf8View (and Dictionary(Int32, Utf8View) for dictionary input).

Are there any user-facing changes?

Yes. hex now returns Utf8View instead of Utf8. Encoded values are unchanged. Callers that match on the physical type (for example ScalarValue::Utf8) need to accept Utf8View.

This is a public return-type change. I cannot add labels on this repo; please apply the api change label if that is still the right category.

Spark hex previously built a Utf8 StringArray for every row. Encodings
of at most 12 bytes (the StringView inline limit) now go through
make_view and never touch a data buffer. Longer encodings are written
once into that buffer. The result type is Utf8View, including dictionary
values. Input null buffers are still reused by pointer clone.

This is the remaining review item from apache#15947 tracked by apache#15986. The
lookup table and criterion benches already landed.

Closes apache#15986
Copilot AI lite review requested due to automatic review settings August 19, 2026 17:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Jefffrey

Copy link
Copy Markdown
Contributor

for anyone looking at this PR please see my comment here:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spark sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[datafusion-spark] Optimize hex function

3 participants