Skip to content

Speed up nullable dictionary hash scattering #26848

Open

Description

@Rich-T-kid

Is your feature request related to a problem or challenge?

Related to #26780.

create_hashes hashes each dictionary value once and then scatters those hashes through the keys. For nullable dictionaries, the scatter currently decodes an Option and branches for every row. Once dictionary value hashes are reused, this O(rows) work becomes a larger share of the hashing cost.

On the existing 8,192-row with_hashes benchmark with 3% null keys, nullable dictionary scatter takes about 5.9 us for one column and 17.0 us for three columns on an Apple M4 Max. The no-null cases take about 2.0 us and 6.1 us respectively.

Describe the solution you would like

Process key validity in 64-row words:

  • reuse the current dense loop for all-valid words
  • pipeline small groups of dictionary hash loads for mostly-valid words
  • walk only set bits for sparse words
  • leave null output slots unchanged, including when dictionary values themselves are null

The benchmark should cover single and composite keys, several dictionary key widths, null densities, slices, and 8/64-row boundaries.

Activity

  1. lakshaydevoo-arch commented on Oct 29, 2026

    @lakshaydevoo-arch

    Hi, I noticed the previous PR exploring dictionary hash scatter optimization was closed without merging.

    Is the nullable dictionary scatter optimization still open for contributions? I'm interested in investigating the 64-row validity bitmap approach and benchmarking it against the current implementation.

  2. Rich-T-kid commented on Oct 29, 2026

    @Rich-T-kid
    ContributorAuthor

    @lakshaydevoo-arch feel free to pick it up. there was a 2x speed up for the null path but I was looking for improvements on the non-null path.

  3. lakshaydevoo-arch commented on Oct 29, 2026

    @lakshaydevoo-arch

    Thanks for the clarification! I'll investigate both the nullable and non-null paths, review the approach from #26849, and benchmark potential improvements before submitting a PR.

  4. lakshaydevoo-arch commented on Oct 29, 2026

    @lakshaydevoo-arch

    @Rich-T-kid how would i assign this issue to myself , because it may take me a day or two to investigate and figure out a fix

  5. Rich-T-kid commented on Oct 29, 2026

    @Rich-T-kid
    ContributorAuthor

    comment take by itself as a comment

  6. lakshaydevoo-arch commented on Oct 29, 2026

    @lakshaydevoo-arch

    take

  7. lakshaydevoo-arch commented on Oct 30, 2026

    @lakshaydevoo-arch

    Hi @Rich-T-kid, thanks for letting me take this up!

    I've started working on #26848 and have prepared benchmarks covering different null densities, dictionary key widths, and sliced arrays.

    Before proceeding with the optimization, I wanted to clarify one thing: would you prefer a separate benchmark-only PR first, followed by the optimization PR, or a single PR containing both benchmarks and the optimization?

    I want to keep the changes focused and aligned with the project's contribution guidelines.

    Thanks!

  8. lakshaydevoo-arch commented on Oct 30, 2026

    @lakshaydevoo-arch

    Before proceeding with the implementation, I wanted to clarify two points about the benchmark coverage:

    1. For the 8/64-row boundaries, would you prefer explicit cases around those boundaries (such as 7/8/9 and 63/64/65 rows), or is testing larger arrays with partial trailing groups sufficient?
    2. For dictionary key widths, would Int8 and Int32 provide sufficient coverage, or would you recommend including Int64 as well?
  9. Rich-T-kid commented on Oct 30, 2026

    @Rich-T-kid
    ContributorAuthor
    1. I think the existing benchmarks cover thsi well enough
    2. this is an interesting point. I think its worth seeing if you can produce noticeable results from smaller key sizes compared to u64, if you can I think its a good idea to contribute these benchmarks upstream otherwise it may not be worth the effort.

    Thank you for driving this! 🚀

  10. lakshaydevoo-arch commented on Oct 30, 2026

    @lakshaydevoo-arch

    I compared Int8, Int32, and UInt64 dictionary keys across 0%, 3%, 50%, and 97% null densities, using the same 8,192-row workloads and three benchmark runs.

    The results showed no consistent performance advantage for smaller key types. Most differences were within the observed benchmark variation, so I don't think additional key-width benchmarks are justified upstream.

    Separately, I've implemented and tested a focused optimization for nullable dictionary hash scattering. On my x86 setup, it reduces execution time by approximately 16–21% for the main 3% null-key cases, with larger improvements at higher null densities.

    Would a PR focused on this nullable-path improvement be useful, keeping non-null-path optimization separate?

  11. Rich-T-kid commented on Oct 30, 2026

    @Rich-T-kid
    ContributorAuthor

    Would a PR focused on this nullable-path improvement be useful, keeping non-null-path optimization separate?

    yeah I think so. two seperate focused PRs would be better in my opinion

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

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions