Repository navigation
Conversation
Reuse collect_bool_word for primitive comparison bitmaps while preserving execution-context allocation and comparison semantics. Cover bitmap boundaries, all primitive types, nulls, and constant operand orientation. Signed-off-by: "Matt Katz" <mhkatz97@gmail.com> Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Use byte packing only for i8/u8 and preserve the existing lane collectors for wider primitive types. The type selection folds away during monomorphization and avoids the wider AVX2 comparison regressions. Signed-off-by: "Matt Katz" <mhkatz97@gmail.com> Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Keep type selection in collect_bits_dispatch and collect_zip_bits_dispatch, with independent narrow collectors and the existing wider collectors. Signed-off-by: "Matt Katz" <mhkatz97@gmail.com> Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Limit the new boundary matrix to the i8/u8 specialization. Existing tests cover the unchanged wider primitive comparison paths. Signed-off-by: "Matt Katz" <mhkatz97@gmail.com> Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Signed-off-by: Matt Katz <mhkatz97@gmail.com>
Merging this PR will regress 8 benchmarks
|
|
This PR has been marked as stale because it has been open for 14 days with no activity. Please comment or remove the stale label if you wish to keep it active, otherwise it will be closed in 7 days |
|
This PR was closed because it has been inactive for 7 days since being marked as stale. |
Summary
Keep an integer array's logical dtype while storing a narrower integer child. For example, a logical
i64array can hold ani8buffer and compare at that width without widening first.Stacked on #9948, the 8-bit primitive comparison optimization. This draft targets
mk/primitive-compare-bitmap; it adds no further changes to the primitive comparison kernels or their existing benchmarks.Changes
NarrowArray::try_newfor an existing narrow child andNarrowArray::encodefor selecting storage from non-null bounds. Preserve signedness and nullability; flatten nested wrappers.Design · Full benchmark report · All results, quartiles, and per-pass medians
Benchmarks
Apple M5 Max, Rust 1.98.0, 1,048,576 non-null rows. Three interleaved passes of 140 samples per case; pooled medians. All Narrow representations retain logical
i64. Compute starts with prebuilt inputs and excludes encoding.< constant< columnThe i8 comparison gains are 4.4× against a constant and 6.0× against a column. Across individual passes these ratios range from 4.33–4.41× and 6.03–7.02×. Absolute times vary across passes; raw variation is included in the report. Buffer sizes exclude array objects, allocator metadata, and RSS.
Filter selects approximately 50%; take gathers N/8 pseudorandom indices. Every operation executes to its final primitive buffer or boolean bitmap.
Encoding i64 into i8, including a fresh bounds scan, costs 334 µs. The constant-comparison savings amortize this in roughly 3–4 comparisons in this fixture. Widening a full i8 child back to i64 costs 189 µs. One comparison alone does not justify converting an existing wide buffer.
Draft limitations
Validation
cargo nextest run -p vortex-array -p vortex-fastlanes: 4,121 passed, one existing skip.cargo test --doc -p vortex-array: 76 passed, 21 ignored.cargo clippy -p vortex-array -p vortex-fastlanes --all-targets --all-features -- -D warnings: passed.cargo clippy --all-targets --all-features: passed across the workspace.cargo +nightly-2026-09-10 fmt --all --checkandgit diff --check: passed.The workspace build warned that clang-format was unavailable for a generated DuckDB header. No C++ or CUDA sources were changed.