Skip to content

IN LIST: add keyed frozen set for large primitive lists - #23015

Closed
geoffreyclaude wants to merge 1 commit into
apache:mainfrom
geoffreyclaude:perf/in_list_direct_probe_filter
Closed

IN LIST: add keyed frozen set for large primitive lists#23015
geoffreyclaude wants to merge 1 commit into
apache:mainfrom
geoffreyclaude:perf/in_list_direct_probe_filter

Conversation

@geoffreyclaude

@geoffreyclaudegeoffreyclaude commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

#23014 handles small primitive IN lists with direct comparisons. For larger 4- and 8-byte lists, integers and floats already use direct-value hashbrown::HashSets; temporal values fall back to the generic table of Arrow array indices and comparator calls.

This PR adds a keyed immutable FrozenSet for fixed-width values. Each bucket stores two values directly; only buckets with additional collisions consult a native hashbrown::HashTable overflow table. The first real member is also the empty-slot sentinel, so the primary table stores values without Option wrappers.

This keeps the common probe small and predictable while retaining exact collision handling. Existing optimizer thresholds are unchanged; any threshold change belongs in a dedicated follow-up PR.

What changes are included in this PR?

  • Adds a reusable keyed FrozenSet with two inline values per bucket and native HashTable overflow handling.
  • Routes larger 4- and 8-byte primitive IN lists through PrimitiveFrozenFilter.
  • Consolidates primitive routing into one type dispatch and removes six legacy integer/float HashSet filters superseded by branchless/frozen routing.
  • Uses Arrow physical compatibility when accepting primitive input arrays.
  • Supports u128 values for later representation-based optimizations without enabling general 128-bit primitive routing here.
  • Covers empty sets, duplicates, the sentinel member, forced collisions, slices, dictionaries, nulls, and physical compatibility.

Are these changes tested?

Yes.

  • cargo fmt --all
  • cargo test -p datafusion-physical-expr --lib expressions::in_list
  • cargo clippy --all-targets --all-features -- -D warnings
  • ./dev/rust_lint.sh
  • RUST_BACKTRACE=1 cargo test --profile ci --exclude datafusion-examples --exclude datafusion-benchmarks --exclude datafusion-cli --workspace --lib --tests --bins --features avro,json,backtrace,extended_tests,recursive_protection,parquet_encryption

Are there any user-facing changes?

No. This is an internal performance optimization only.

Local benchmark snapshot

Built and run with release-nonlto, filtered to the relevant large primitive-list rows:

cargo bench -p datafusion-physical-expr --profile release-nonlto --bench in_list_strategy -- <filter> --save-baseline <baseline>

Filters used: primitive/i32/large_list and primitive/i64/large_list.

Method: directly compared Criterion slope point estimates from isolated saved baselines. The expression is constructed outside the timed loop. Lower is better; changes within +/-5% are treated as noise.

Compared baselines: #23014 -> #23015

Relevant scope: the 12 large primitive-list rows shared with #23014.

Summary: 12 relevant rows, 12 faster, 0 slower, 0 within +/-5%. Geometric-mean time decreased by 45.4%.

A separate extension run covered eight added 1K/10K-list rows. All eight improved, with a 43.6% geometric-mean decrease.

Largest relevant deltas:

BenchmarkBeforeAfterChange
primitive/i64/large_list/list=32/match=50%35.01 us11.86 us-66.1% (2.95x faster)
primitive/i64/large_list/list=17/match=50%35.23 us12.06 us-65.8% (2.92x faster)
primitive/i64/large_list/list=128/match=50%32.66 us11.72 us-64.1% (2.79x faster)
primitive/i32/large_list/list=33/match=50%38.13 us15.30 us-59.9% (2.49x faster)
primitive/i32/large_list/list=64/match=50%36.89 us16.26 us-55.9% (2.27x faster)
primitive/i32/large_list/list=256/match=50%34.67 us15.90 us-54.1% (2.18x faster)
Full relevant table (12 rows)
BenchmarkBeforeAfterChange
primitive/i32/large_list/list=33/match=0%17.19 us13.14 us-23.6% (1.31x faster)
primitive/i32/large_list/list=33/match=50%38.13 us15.30 us-59.9% (2.49x faster)
primitive/i32/large_list/list=64/match=0%17.61 us13.72 us-22.1% (1.28x faster)
primitive/i32/large_list/list=64/match=50%36.89 us16.26 us-55.9% (2.27x faster)
primitive/i32/large_list/list=256/match=0%18.00 us13.31 us-26.1% (1.35x faster)
primitive/i32/large_list/list=256/match=50%34.67 us15.90 us-54.1% (2.18x faster)
primitive/i64/large_list/list=17/match=0%20.20 us11.47 us-43.2% (1.76x faster)
primitive/i64/large_list/list=17/match=50%35.23 us12.06 us-65.8% (2.92x faster)
primitive/i64/large_list/list=32/match=0%16.96 us15.85 us-6.5% (1.07x faster)
primitive/i64/large_list/list=32/match=50%35.01 us11.86 us-66.1% (2.95x faster)
primitive/i64/large_list/list=128/match=0%17.99 us16.04 us-10.8% (1.12x faster)
primitive/i64/large_list/list=128/match=50%32.66 us11.72 us-64.1% (2.79x faster)

@github-actionsgithub-actionsBot added the physical-expr Changes to the physical-expr crates label Jun 18, 2026
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch 2 times, most recently from 12ca843 to 0111ce5CompareJune 18, 2026 09:12
@geoffreyclaudegeoffreyclaude changed the title Implement Direct Probe (Hash) Filter for large primitive listsIN LIST: add direct-probe hash filter for large primitive listsJun 18, 2026
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch 3 times, most recently from a109166 to 2e20173CompareJune 19, 2026 05:55
@github-actionsgithub-actionsBot added the auto detected api change Auto detected API change label Jun 19, 2026
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from 2e20173 to f0c8d4dCompareJune 22, 2026 13:50
@github-actionsgithub-actionsBot removed the auto detected api change Auto detected API change label Jun 22, 2026
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch 9 times, most recently from 436582f to 57a8e6fCompareJune 26, 2026 16:21
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch 4 times, most recently from 2c36a1f to 6d59f07CompareJuly 2, 2026 08:54
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from 6d59f07 to c7dfb7aCompareJuly 8, 2026 11:57
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch 2 times, most recently from 218844d to a6f0778CompareJuly 8, 2026 13:34
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from a6f0778 to 15314e6CompareJuly 21, 2026 12:16
@geoffreyclaudegeoffreyclaude changed the title IN LIST: add direct-probe hash filter for large primitive listsIN LIST: use keyed HashTable for large primitive listsJul 21, 2026
@codecov-commenter

codecov-commenter commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.03115% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.90%. Comparing base (26fbf4d) to head (48c32f6).
⚠️ Report is 32 commits behind head on main.

Files with missing linesPatch %Lines
...l-expr/src/expressions/in_list/primitive_filter.rs83.96%6 Missing and 11 partials ⚠️
.../physical-expr/src/expressions/in_list/strategy.rs86.81%1 Missing and 11 partials ⚠️
...hysical-expr/src/expressions/in_list/frozen_set.rs97.58%1 Missing and 2 partials ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #23015 +/- ##
==========================================
+ Coverage 80.89% 80.90% +0.01% 
==========================================
Files 1102 1103 +1 Lines 376093 376322 +229 Branches 376093 376322 +229 ==========================================
+ Hits 304239 304482 +243 + Misses 53748 53714 -34 - Partials 18106 18126 +20 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from 15314e6 to a8edfdbCompareJuly 21, 2026 19:24
@geoffreyclaudegeoffreyclaude changed the title IN LIST: use keyed HashTable for large primitive listsIN LIST: add keyed frozen set for large primitive listsJul 21, 2026
pullBot pushed a commit to TCeason/arrow-datafusion that referenced this pull request Jul 26, 2026
## Which issue does this PR close?
- Part of apache#19241.
- Stacked on [apache#23311](apache#23311).
- Next in stack: apache#23015.
- Extracted from apache#19390.
## Rationale for this change
For very small `IN` lists, building or probing a hash table can be more
work than just comparing the input value with each constant.
For example, for `x IN (10, 20, 30)`, the fast path can behave like:
```text
x == 10 OR x == 20 OR x == 30
```
Because the list is tiny, those comparisons are cheap. The
implementation stores the constants in a fixed-size array and checks
them with a compact comparison chain.
“Branchless” here means the comparisons are combined without stopping at
the first match. That can be faster for these small fixed-width lists
because the CPU gets a predictable sequence of simple operations instead
of hash-table setup and probe logic.
For primitive values that are not already plain unsigned integers, this
PR keeps the logical Arrow type explicit and uses a matching same-width
comparison representation only inside the branchless filter. For
example, `Float16` uses `UInt16` storage, `Float32` uses `UInt32`
storage, and `TimestampNanosecond` uses `UInt64` storage. `Decimal128`
and `IntervalMonthDayNano` use their own 16-byte native representation.
This preserves bit-pattern equality while relying on Arrow's native
primitive compatibility rules: timestamp timezone metadata and
Decimal128 precision/scale metadata may differ, while incompatible
primitive representations remain rejected.
## What changes are included in this PR?
- Adds a const-generic `BranchlessFilter` for small primitive `IN`
lists.
- Adds thresholds for when this path is used:
- up to 16 values for 1-byte types
- up to 8 values for 2-byte types
- up to 32 values for 4-byte types
- up to 16 values for 8-byte types
- up to 4 values for 16-byte types
- Keeps dispatch concrete and explicit in `strategy.rs`.
- Maps each optimized logical type to the comparison representation used
by the branchless filter:
- `Int8` -> `UInt8`
- `Int16`, `Float16` -> `UInt16`
- `Int32`, `Float32`, `Date32`, `Time32` -> `UInt32`
- `Int64`, `Float64`, `Date64`, `Time64`, `Timestamp`, `Duration` ->
`UInt64`
- `Decimal128`, `IntervalMonthDayNano` -> their native 16-byte
representation
- Leaves larger 1-byte and 2-byte lists on the existing bitmap filters.
- Leaves larger 4-byte and 8-byte lists on the existing hash/generic
paths.
- Leaves wider primitive types such as `Decimal256` and unsupported
complex types on the generic path.
- Keeps the same `IN` / `NOT IN` null behavior as the rest of the stack.
- Adds focused coverage for branchless null handling, signed boundary
values, slices, Float16/Float32/Float64 bit patterns, compatible
timestamp/Decimal128 metadata, incompatible timestamp units,
IntervalMonthDayNano values, and same-width wrong-type probe rejection.
## Are these changes tested?
Yes.
- `cargo fmt --all -- --check`
- `cargo test -p datafusion-physical-expr expressions::in_list --lib`
- `cargo test -p datafusion-physical-expr --bench in_list_strategy
--no-run`
- `cargo clippy --all-targets --all-features -- -D warnings`
## Are there any user-facing changes?
No. This is an internal performance optimization only.
## Local benchmark snapshot
Built and run with `release-nonlto`, filtered to the relevant small
primitive-list rows:
```bash
cargo bench -p datafusion-physical-expr --profile release-nonlto --bench in_list_strategy -- <filter> --save-baseline <baseline>
```
Filters used: `narrow_integer`, `primitive/i32/small_list`,
`primitive/i64/small_list`, `f32/small_list`, `timestamp_ns/small_list`,
and `interval_month_day_nano/small_list`.
Method: directly compared Criterion's raw sample minima (`min(time /
iterations)`) from `sample.json`. Lower is better; changes within +/-5%
are treated as noise.
Compared baselines:
[apache#23311](apache#23311) ->
[apache#23014](apache#23014)
Relevant scope: small primitive-list rows.
Summary: 39 relevant rows, 28 faster, 0 slower, 11 within +/-5%.
Largest relevant deltas:
| Benchmark | Before | After | Change |
|---|---:|---:|---:|
| `timestamp_ns/small_list/list=4/match=50%` | 46.55 us | 3.17 us |
-93.2% (14.69x faster) |
| `f32/small_list/list=4/match=50%` | 33.93 us | 3.04 us | -91.0%
(11.15x faster) |
| `primitive/i32/small_list/list=4/match=50%` | 32.63 us | 3.08 us |
-90.5% (10.58x faster) |
| `primitive/i64/small_list/list=4/match=50%` | 33.55 us | 3.18 us |
-90.5% (10.54x faster) |
| `timestamp_ns/small_list/list=4/match=0%` | 19.57 us | 3.18 us |
-83.8% (6.16x faster) |
| `f32/small_list/list=4/match=0%` | 18.14 us | 3.05 us | -83.2% (5.95x
faster) |
| `primitive/i32/small_list/list=4/match=0%` | 17.00 us | 3.04 us |
-82.1% (5.59x faster) |
| `primitive/i64/small_list/list=4/match=0%` | 17.12 us | 3.22 us |
-81.2% (5.31x faster) |
| `primitive/i32/small_list/list=16/match=50%/NOT_IN` | 31.98 us | 7.26
us | -77.3% (4.41x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%` | 29.35
us | 7.32 us | -75.1% (4.01x faster) |
| `timestamp_ns/small_list/list=16/match=50%` | 45.32 us | 11.79 us |
-74.0% (3.84x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=50%` | 25.89
us | 7.31 us | -71.8% (3.54x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%/NOT_IN` |
26.05 us | 7.42 us | -71.5% (3.51x faster) |
| `interval_month_day_nano/small_list/list=4/match=50%` | 52.94 us |
15.52 us | -70.7% (3.41x faster) |
| `f32/small_list/list=32/match=50%` | 38.78 us | 13.27 us | -65.8%
(2.92x faster) |
| `primitive/i64/small_list/list=16/match=50%` | 29.46 us | 11.76 us |
-60.1% (2.50x faster) |
<details>
<summary>Full relevant table (39 rows)</summary>
| Benchmark | Before | After | Change |
|---|---:|---:|---:|
| `narrow_integer/u8/list=4/match=0%` | 3.86 us | 2.79 us | -27.8%
(1.38x faster) |
| `narrow_integer/u8/list=4/match=50%` | 3.84 us | 2.78 us | -27.7%
(1.38x faster) |
| `narrow_integer/u8/list=16/match=0%` | 3.88 us | 3.85 us | -0.8%
(within noise) |
| `narrow_integer/u8/list=16/match=50%` | 3.84 us | 3.86 us | +0.5%
(within noise) |
| `narrow_integer/i16/list=4/match=0%` | 3.93 us | 3.18 us | -19.1%
(1.24x faster) |
| `narrow_integer/i16/list=4/match=50%` | 3.92 us | 3.16 us | -19.5%
(1.24x faster) |
| `narrow_integer/i16/list=64/match=0%` | 3.96 us | 3.82 us | -3.5%
(within noise) |
| `narrow_integer/i16/list=64/match=50%` | 3.91 us | 3.80 us | -2.9%
(within noise) |
| `narrow_integer/i16/list=256/match=0%` | 3.90 us | 3.81 us | -2.5%
(within noise) |
| `narrow_integer/i16/list=256/match=50%` | 3.97 us | 3.81 us | -4.1%
(within noise) |
| `narrow_integer/f16/list=4/match=0%` | 3.87 us | 3.16 us | -18.5%
(1.23x faster) |
| `narrow_integer/f16/list=4/match=50%` | 3.94 us | 3.15 us | -20.2%
(1.25x faster) |
| `narrow_integer/f16/list=64/match=0%` | 3.87 us | 3.84 us | -0.6%
(within noise) |
| `narrow_integer/f16/list=64/match=50%` | 3.93 us | 3.85 us | -1.9%
(within noise) |
| `narrow_integer/f16/list=256/match=0%` | 3.90 us | 3.84 us | -1.5%
(within noise) |
| `narrow_integer/f16/list=256/match=50%` | 3.87 us | 3.91 us | +1.2%
(within noise) |
| `nulls/narrow_integer/u8/list=16/match=50%/nulls=20%` | 3.92 us | 4.02
us | +2.5% (within noise) |
| `primitive/i32/small_list/list=4/match=0%` | 17.00 us | 3.04 us |
-82.1% (5.59x faster) |
| `primitive/i32/small_list/list=4/match=50%` | 32.63 us | 3.08 us |
-90.5% (10.58x faster) |
| `primitive/i32/small_list/list=32/match=0%` | 16.34 us | 13.33 us |
-18.5% (1.23x faster) |
| `primitive/i32/small_list/list=32/match=50%` | 31.17 us | 13.31 us |
-57.3% (2.34x faster) |
| `primitive/i32/small_list/list=16/match=50%/NOT_IN` | 31.98 us | 7.26
us | -77.3% (4.41x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%` | 29.35
us | 7.32 us | -75.1% (4.01x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%/NOT_IN` |
26.05 us | 7.42 us | -71.5% (3.51x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=50%` | 25.89
us | 7.31 us | -71.8% (3.54x faster) |
| `primitive/i64/small_list/list=4/match=0%` | 17.12 us | 3.22 us |
-81.2% (5.31x faster) |
| `primitive/i64/small_list/list=4/match=50%` | 33.55 us | 3.18 us |
-90.5% (10.54x faster) |
| `primitive/i64/small_list/list=16/match=0%` | 16.34 us | 11.93 us |
-27.0% (1.37x faster) |
| `primitive/i64/small_list/list=16/match=50%` | 29.46 us | 11.76 us |
-60.1% (2.50x faster) |
| `f32/small_list/list=4/match=0%` | 18.14 us | 3.05 us | -83.2% (5.95x
faster) |
| `f32/small_list/list=4/match=50%` | 33.93 us | 3.04 us | -91.0%
(11.15x faster) |
| `f32/small_list/list=32/match=0%` | 22.05 us | 13.43 us | -39.1%
(1.64x faster) |
| `f32/small_list/list=32/match=50%` | 38.78 us | 13.27 us | -65.8%
(2.92x faster) |
| `timestamp_ns/small_list/list=4/match=0%` | 19.57 us | 3.18 us |
-83.8% (6.16x faster) |
| `timestamp_ns/small_list/list=4/match=50%` | 46.55 us | 3.17 us |
-93.2% (14.69x faster) |
| `timestamp_ns/small_list/list=16/match=0%` | 19.73 us | 12.07 us |
-38.8% (1.63x faster) |
| `timestamp_ns/small_list/list=16/match=50%` | 45.32 us | 11.79 us |
-74.0% (3.84x faster) |
| `interval_month_day_nano/small_list/list=4/match=0%` | 20.12 us |
13.20 us | -34.4% (1.52x faster) |
| `interval_month_day_nano/small_list/list=4/match=50%` | 52.94 us |
15.52 us | -70.7% (3.41x faster) |
</details>
---------
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from a8edfdb to c56ea59CompareAugust 4, 2026 09:14
@geoffreyclaude
geoffreyclaudeforce-pushed the perf/in_list_direct_probe_filter branch from c56ea59 to 48c32f6CompareAugust 4, 2026 13:38
kosiew pushed a commit to kosiew/datafusion that referenced this pull request Aug 12, 2026
## Which issue does this PR close?
- Part of apache#19241.
- Stacked on [apache#23311](apache#23311).
- Next in stack: apache#23015.
- Extracted from apache#19390.
## Rationale for this change
For very small `IN` lists, building or probing a hash table can be more
work than just comparing the input value with each constant.
For example, for `x IN (10, 20, 30)`, the fast path can behave like:
```text
x == 10 OR x == 20 OR x == 30
```
Because the list is tiny, those comparisons are cheap. The
implementation stores the constants in a fixed-size array and checks
them with a compact comparison chain.
“Branchless” here means the comparisons are combined without stopping at
the first match. That can be faster for these small fixed-width lists
because the CPU gets a predictable sequence of simple operations instead
of hash-table setup and probe logic.
For primitive values that are not already plain unsigned integers, this
PR keeps the logical Arrow type explicit and uses a matching same-width
comparison representation only inside the branchless filter. For
example, `Float16` uses `UInt16` storage, `Float32` uses `UInt32`
storage, and `TimestampNanosecond` uses `UInt64` storage. `Decimal128`
and `IntervalMonthDayNano` use their own 16-byte native representation.
This preserves bit-pattern equality while relying on Arrow's native
primitive compatibility rules: timestamp timezone metadata and
Decimal128 precision/scale metadata may differ, while incompatible
primitive representations remain rejected.
## What changes are included in this PR?
- Adds a const-generic `BranchlessFilter` for small primitive `IN`
lists.
- Adds thresholds for when this path is used:
- up to 16 values for 1-byte types
- up to 8 values for 2-byte types
- up to 32 values for 4-byte types
- up to 16 values for 8-byte types
- up to 4 values for 16-byte types
- Keeps dispatch concrete and explicit in `strategy.rs`.
- Maps each optimized logical type to the comparison representation used
by the branchless filter:
- `Int8` -> `UInt8`
- `Int16`, `Float16` -> `UInt16`
- `Int32`, `Float32`, `Date32`, `Time32` -> `UInt32`
- `Int64`, `Float64`, `Date64`, `Time64`, `Timestamp`, `Duration` ->
`UInt64`
- `Decimal128`, `IntervalMonthDayNano` -> their native 16-byte
representation
- Leaves larger 1-byte and 2-byte lists on the existing bitmap filters.
- Leaves larger 4-byte and 8-byte lists on the existing hash/generic
paths.
- Leaves wider primitive types such as `Decimal256` and unsupported
complex types on the generic path.
- Keeps the same `IN` / `NOT IN` null behavior as the rest of the stack.
- Adds focused coverage for branchless null handling, signed boundary
values, slices, Float16/Float32/Float64 bit patterns, compatible
timestamp/Decimal128 metadata, incompatible timestamp units,
IntervalMonthDayNano values, and same-width wrong-type probe rejection.
## Are these changes tested?
Yes.
- `cargo fmt --all -- --check`
- `cargo test -p datafusion-physical-expr expressions::in_list --lib`
- `cargo test -p datafusion-physical-expr --bench in_list_strategy
--no-run`
- `cargo clippy --all-targets --all-features -- -D warnings`
## Are there any user-facing changes?
No. This is an internal performance optimization only.
## Local benchmark snapshot
Built and run with `release-nonlto`, filtered to the relevant small
primitive-list rows:
```bash
cargo bench -p datafusion-physical-expr --profile release-nonlto --bench in_list_strategy -- <filter> --save-baseline <baseline>
```
Filters used: `narrow_integer`, `primitive/i32/small_list`,
`primitive/i64/small_list`, `f32/small_list`, `timestamp_ns/small_list`,
and `interval_month_day_nano/small_list`.
Method: directly compared Criterion's raw sample minima (`min(time /
iterations)`) from `sample.json`. Lower is better; changes within +/-5%
are treated as noise.
Compared baselines:
[apache#23311](apache#23311) ->
[apache#23014](apache#23014)
Relevant scope: small primitive-list rows.
Summary: 39 relevant rows, 28 faster, 0 slower, 11 within +/-5%.
Largest relevant deltas:
| Benchmark | Before | After | Change |
|---|---:|---:|---:|
| `timestamp_ns/small_list/list=4/match=50%` | 46.55 us | 3.17 us |
-93.2% (14.69x faster) |
| `f32/small_list/list=4/match=50%` | 33.93 us | 3.04 us | -91.0%
(11.15x faster) |
| `primitive/i32/small_list/list=4/match=50%` | 32.63 us | 3.08 us |
-90.5% (10.58x faster) |
| `primitive/i64/small_list/list=4/match=50%` | 33.55 us | 3.18 us |
-90.5% (10.54x faster) |
| `timestamp_ns/small_list/list=4/match=0%` | 19.57 us | 3.18 us |
-83.8% (6.16x faster) |
| `f32/small_list/list=4/match=0%` | 18.14 us | 3.05 us | -83.2% (5.95x
faster) |
| `primitive/i32/small_list/list=4/match=0%` | 17.00 us | 3.04 us |
-82.1% (5.59x faster) |
| `primitive/i64/small_list/list=4/match=0%` | 17.12 us | 3.22 us |
-81.2% (5.31x faster) |
| `primitive/i32/small_list/list=16/match=50%/NOT_IN` | 31.98 us | 7.26
us | -77.3% (4.41x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%` | 29.35
us | 7.32 us | -75.1% (4.01x faster) |
| `timestamp_ns/small_list/list=16/match=50%` | 45.32 us | 11.79 us |
-74.0% (3.84x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=50%` | 25.89
us | 7.31 us | -71.8% (3.54x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%/NOT_IN` |
26.05 us | 7.42 us | -71.5% (3.51x faster) |
| `interval_month_day_nano/small_list/list=4/match=50%` | 52.94 us |
15.52 us | -70.7% (3.41x faster) |
| `f32/small_list/list=32/match=50%` | 38.78 us | 13.27 us | -65.8%
(2.92x faster) |
| `primitive/i64/small_list/list=16/match=50%` | 29.46 us | 11.76 us |
-60.1% (2.50x faster) |
<details>
<summary>Full relevant table (39 rows)</summary>
| Benchmark | Before | After | Change |
|---|---:|---:|---:|
| `narrow_integer/u8/list=4/match=0%` | 3.86 us | 2.79 us | -27.8%
(1.38x faster) |
| `narrow_integer/u8/list=4/match=50%` | 3.84 us | 2.78 us | -27.7%
(1.38x faster) |
| `narrow_integer/u8/list=16/match=0%` | 3.88 us | 3.85 us | -0.8%
(within noise) |
| `narrow_integer/u8/list=16/match=50%` | 3.84 us | 3.86 us | +0.5%
(within noise) |
| `narrow_integer/i16/list=4/match=0%` | 3.93 us | 3.18 us | -19.1%
(1.24x faster) |
| `narrow_integer/i16/list=4/match=50%` | 3.92 us | 3.16 us | -19.5%
(1.24x faster) |
| `narrow_integer/i16/list=64/match=0%` | 3.96 us | 3.82 us | -3.5%
(within noise) |
| `narrow_integer/i16/list=64/match=50%` | 3.91 us | 3.80 us | -2.9%
(within noise) |
| `narrow_integer/i16/list=256/match=0%` | 3.90 us | 3.81 us | -2.5%
(within noise) |
| `narrow_integer/i16/list=256/match=50%` | 3.97 us | 3.81 us | -4.1%
(within noise) |
| `narrow_integer/f16/list=4/match=0%` | 3.87 us | 3.16 us | -18.5%
(1.23x faster) |
| `narrow_integer/f16/list=4/match=50%` | 3.94 us | 3.15 us | -20.2%
(1.25x faster) |
| `narrow_integer/f16/list=64/match=0%` | 3.87 us | 3.84 us | -0.6%
(within noise) |
| `narrow_integer/f16/list=64/match=50%` | 3.93 us | 3.85 us | -1.9%
(within noise) |
| `narrow_integer/f16/list=256/match=0%` | 3.90 us | 3.84 us | -1.5%
(within noise) |
| `narrow_integer/f16/list=256/match=50%` | 3.87 us | 3.91 us | +1.2%
(within noise) |
| `nulls/narrow_integer/u8/list=16/match=50%/nulls=20%` | 3.92 us | 4.02
us | +2.5% (within noise) |
| `primitive/i32/small_list/list=4/match=0%` | 17.00 us | 3.04 us |
-82.1% (5.59x faster) |
| `primitive/i32/small_list/list=4/match=50%` | 32.63 us | 3.08 us |
-90.5% (10.58x faster) |
| `primitive/i32/small_list/list=32/match=0%` | 16.34 us | 13.33 us |
-18.5% (1.23x faster) |
| `primitive/i32/small_list/list=32/match=50%` | 31.17 us | 13.31 us |
-57.3% (2.34x faster) |
| `primitive/i32/small_list/list=16/match=50%/NOT_IN` | 31.98 us | 7.26
us | -77.3% (4.41x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%` | 29.35
us | 7.32 us | -75.1% (4.01x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=20%/NOT_IN` |
26.05 us | 7.42 us | -71.5% (3.51x faster) |
| `nulls/primitive/i32/small_list/list=16/match=50%/nulls=50%` | 25.89
us | 7.31 us | -71.8% (3.54x faster) |
| `primitive/i64/small_list/list=4/match=0%` | 17.12 us | 3.22 us |
-81.2% (5.31x faster) |
| `primitive/i64/small_list/list=4/match=50%` | 33.55 us | 3.18 us |
-90.5% (10.54x faster) |
| `primitive/i64/small_list/list=16/match=0%` | 16.34 us | 11.93 us |
-27.0% (1.37x faster) |
| `primitive/i64/small_list/list=16/match=50%` | 29.46 us | 11.76 us |
-60.1% (2.50x faster) |
| `f32/small_list/list=4/match=0%` | 18.14 us | 3.05 us | -83.2% (5.95x
faster) |
| `f32/small_list/list=4/match=50%` | 33.93 us | 3.04 us | -91.0%
(11.15x faster) |
| `f32/small_list/list=32/match=0%` | 22.05 us | 13.43 us | -39.1%
(1.64x faster) |
| `f32/small_list/list=32/match=50%` | 38.78 us | 13.27 us | -65.8%
(2.92x faster) |
| `timestamp_ns/small_list/list=4/match=0%` | 19.57 us | 3.18 us |
-83.8% (6.16x faster) |
| `timestamp_ns/small_list/list=4/match=50%` | 46.55 us | 3.17 us |
-93.2% (14.69x faster) |
| `timestamp_ns/small_list/list=16/match=0%` | 19.73 us | 12.07 us |
-38.8% (1.63x faster) |
| `timestamp_ns/small_list/list=16/match=50%` | 45.32 us | 11.79 us |
-74.0% (3.84x faster) |
| `interval_month_day_nano/small_list/list=4/match=0%` | 20.12 us |
13.20 us | -34.4% (1.52x faster) |
| `interval_month_day_nano/small_list/list=4/match=50%` | 52.94 us |
15.52 us | -70.7% (3.41x faster) |
</details>
---------
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physical-exprChanges to the physical-expr crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@geoffreyclaude@codecov-commenter