Skip to content

GH-55254: [C++][Compute] Prefix-aware early rejection for StringView equality kernels - #55425

Open
Awesome06 wants to merge 2 commits into
apache:mainfrom
Awesome06:gh-55254-stringview-prefix-early-reject
Open

Awesome06 wants to merge 2 commits into
apache:mainfrom
Awesome06:gh-55254-stringview-prefix-early-reject

Conversation

@Awesome06

@Awesome06 Awesome06 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Rationale for this change

In #55171, direct comparison kernels were added between StringView/BinaryView and offset-based string types. Those kernels relied on applicator::ScalarBinary with ArrayIterator<BinaryViewType>, which eagerly calls util::FromBinaryView and resolves variadic payload pointers for every element regardless of match outcome.

As discussed in #55254, equality comparisons (equal, not_equal) can check the view's 4-byte inline prefix and string length before accessing payload buffers, rejecting mismatches early.

What changes are included in this PR?

  1. util::EqualBinaryViewString: Added in arrow/util/binary_view_util.h to compare a BinaryViewType::c_type with contiguous string data. It checks length and 4-byte prefix before dereferencing view variadic buffers.
  2. Dedicated equality kernels: Implemented ViewCompareViewEqual and ViewCompareStringEqual in scalar_compare.cc, replacing eager iterator resolution for equal and not_equal.
  3. Register-pinned scalar comparisons: For array-scalar operations, unpacked scalar length and prefix are pinned in registers outside the loop, avoiding repeated scalar lookups.
  4. Tests: Extended TestBinaryViewCompareKernel.ArrayArray and TestBinaryViewCompareKernel.ArrayScalar with cases covering prefix mismatch, out-of-line equality, null bytes, and long strings.

Are these changes tested?

Yes, extended existing parameterized tests in scalar_compare_test.cc.

Are there any user-facing changes?

No.

Was AI used for this PR?

AI was used to assist with kernel registration and testing under human direction.

PR code and description written by:

  • Human
  • AI

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

Copilot AI balanced review requested due to automatic review settings November 6, 2026 08:56

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 insufficient remaining quota. Try requesting a review at a lower effort level.

@github-actions github-actions Bot added the awaiting review Awaiting review label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

⚠️ GitHub issue #55254 has been automatically assigned in GitHub to PR creator.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

⚠️ GitHub issue #55254 has no components, please add labels for components.

@Awesome06

Awesome06 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

@dmitry-chirkov-dremio Based on our prior conversation, here are the benchmark measurements evaluating the direct prefix path versus the adaptive sampling heuristic on GH-55254.

Benchmark Notes: Direct Prefix (Option A) vs. Adaptive Sampling (Option B)

We evaluated the adaptive heuristic prototyping 32 evenly spaced sampled pairs per batch (triggering the prefix path on >= 4 sample rejections for mixed types, >= 8 for view/view, and falling back to the baseline executor below 4,096 rows):

Comparative Benchmark Results:

Workload Baseline (#55171) Option A (Current PR) Option B (Adaptive)
View vs String, 131k * 8 B, equal 539.12 us 366.16 us (1.47x) 492.86 us (1.09x)
View vs String, 131k * 64 B, equal 629.59 us 735.81 us (0.86x) 638.10 us (0.98x)
View vs String, 131k * 64 B, ~50% mismatch 643.44 us 521.43 us (1.23x) 536.20 us (1.20x)
View vs String, 131k * 64 B, 100% mismatch 657.29 us 307.06 us (2.14x) 327.67 us (2.01x)
View vs String, 131k * 64 B, prefix collision 794.78 us 670.92 us (1.18x) 732.25 us (1.09x)
View vs View, 131k * 64 B, ~50% mismatch 612.80 us 340.44 us (1.80x) 358.12 us (1.71x)
View vs String, 2k * 64 B, < 4,096 rows 10.27 us 4.82 us (2.13x) 10.25 us (1.00x)
Array vs Scalar, 131k * 32 B, 1% match 400.32 us 85.72 us (4.67x) 85.72 us (4.67x)

Note: Symmetric operand order (String vs View), 64-bit offsets (LargeString), and sliced arrays follow identical code paths and yield symmetric performance.

Takeaways:

  • Trade-off on Equal Strings: Fully matching out-of-line strings (> 12 B) see a minor ~14% regression in Option A because the prefix check is redundant before memcmp. In contrast, inlined strings (< 12 B) are 1.47x faster because they resolve with two 64-bit integer comparisons without calling memcmp.
  • Heuristic Overhead: Option B avoids the 14% regression on large matching strings, but the 32-sample probe and branch overhead offset gains on smaller batches (< 4k rows where it falls back) without improving mismatch throughput.
  • Simplicity: Option A delivers consistent 1.8x–2.1x speedups on array mismatches and 4.67x on selective scalar filters with cleaner, stateless dispatch logic.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

⚠️ GitHub issue #55254 has no components, please add labels for components.

…gView equality kernels

### Rationale for this change

In apache#55171, direct comparison kernels were added between StringView/BinaryView and offset-based string types. Those kernels relied on `applicator::ScalarBinary` with `ArrayIterator<BinaryViewType>`, which eagerly calls `util::FromBinaryView` and resolves variadic payload pointers for every element regardless of match outcome.

As discussed in apache#55254, equality comparisons (`equal`, `not_equal`) can check the view's 4-byte inline prefix and string length before accessing payload buffers, rejecting mismatches early.

### What changes are included in this PR?

1. `util::EqualBinaryViewString`: Added in `arrow/util/binary_view_util.h` to compare a `BinaryViewType::c_type` with contiguous string data. It checks length and 4-byte prefix before dereferencing view variadic buffers.
2. Dedicated equality kernels: Implemented `ViewCompareViewEqual` and `ViewCompareStringEqual` in `scalar_compare.cc`, replacing eager iterator resolution for `equal` and `not_equal`.
3. Register-pinned scalar comparisons: For array-scalar operations, unpacked scalar length and prefix are pinned in registers outside the loop, avoiding repeated scalar lookups.
4. Tests: Extended `TestBinaryViewCompareKernel.ArrayArray` and `TestBinaryViewCompareKernel.ArrayScalar` with cases covering prefix mismatch, out-of-line equality, null bytes, and long strings.

### Are these changes tested?

Yes, extended existing parameterized tests in `scalar_compare_test.cc`.

### Are there any user-facing changes?

No.

### Was AI used for this PR?

AI was used to assist with kernel registration and testing under human direction.

**PR code and description written by:**

- [ ] Human
- [x] AI

**Reviewed before submission by:**

- [x] Human
- [x] AI
- [ ] Not reviewed

* GitHub Issue: apache#55254
@Awesome06
Awesome06 force-pushed the gh-55254-stringview-prefix-early-reject branch from 3660d80 to de62926 Compare November 6, 2026 09:09
Copilot AI balanced review requested due to automatic review settings November 6, 2026 09:09

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 insufficient remaining quota. Try requesting a review at a lower effort level.

…uality kernels

- Extract shared ViewArrayCompareBinaryScalarEqual helper to decouple View and String kernel structs.
- Optimize variadic payload comparisons by skipping the verified 4-byte prefix.
- Use stateless indexed offset traversal in ViewCompareStringEqual::ArrayArray.
- Clean up boolean expressions and add Doxygen API documentation in binary_view_util.h.
- Add asymmetric slice test coverage in scalar_compare_test.cc.
Copilot AI balanced review requested due to automatic review settings November 6, 2026 10:12

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 insufficient remaining quota. Try requesting a review at a lower effort level.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants