Skip to content

perf: use direct pointer reads in SparkUnsafeObject accessors#3658

Draft
andygrove wants to merge 3 commits intoapache:mainfrom
andygrove:perf/spark-unsafe-aligned-reads
Draft

perf: use direct pointer reads in SparkUnsafeObject accessors#3658
andygrove wants to merge 3 commits intoapache:mainfrom
andygrove:perf/spark-unsafe-aligned-reads

Conversation

@andygrove
Copy link
Member

@andygrove andygrove commented Mar 10, 2026

Summary

  • Replace from_raw_parts + try_into().unwrap() + from_le_bytes() with direct pointer dereferences (*(addr as *const T)) in all SparkUnsafeObject trait accessors (get_byte, get_short, get_int, get_long, get_float, get_double, get_date, get_timestamp)
  • Apply the same optimization to SparkUnsafeArray::new element count read

Rationale

The previous from_raw_parts + try_into().unwrap() + from_le_bytes pattern added three layers of abstraction per read that compiled to unnecessary overhead. These accessors are on the hottest path in row-to-columnar conversion used by JVM shuffle.

Replace slice construction + try_into().unwrap() + from_le_bytes() with
direct pointer dereferences in all SparkUnsafeObject trait accessors.

Both SparkUnsafeRow and SparkUnsafeArray guarantee natural alignment for
field access: UnsafeRow fields are at 8-byte aligned offsets (bitset
width is multiple of 8, each slot is 8 bytes, JVM allocates aligned
memory), and UnsafeArray elements are at naturally aligned offsets
(header is 8-byte aligned, elements are at element_size stride).

This eliminates three layers of abstraction per read (from_raw_parts,
try_into().unwrap(), from_le_bytes) on the hottest path in row-to-
columnar conversion.
@mbutrovich mbutrovich self-requested a review March 11, 2026 00:10
@andygrove andygrove marked this pull request as draft March 11, 2026 00:53
SparkUnsafeArray elements may not be naturally aligned (e.g., i64
elements at 4-byte-aligned offsets). Use read_unaligned() instead of
direct pointer dereferences for all multi-byte accessors. This is
still faster than the original from_raw_parts + try_into + from_le_bytes
chain while being safe for both SparkUnsafeRow (always aligned) and
SparkUnsafeArray (potentially unaligned).
@andygrove andygrove changed the title perf: use direct aligned pointer reads in SparkUnsafeObject accessors perf: use direct pointer reads in SparkUnsafeObject accessors Mar 11, 2026
@mbutrovich
Copy link
Contributor

Current code compiles down to a single load anyway ldr x9, [x0] so I suspect we won't see a performance difference but I think what you're proposing is more readable.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants