Skip to content

VarBin: build views straight into a VarBinViewBuilder - #9127

Open
robert3005 wants to merge 1 commit into
rk/onpair-decode-into-builderfrom
rk/varbin-to-varbinview-builder
Open

VarBin: build views straight into a VarBinViewBuilder#9127
robert3005 wants to merge 1 commit into
rk/onpair-decode-into-builderfrom
rk/varbin-to-varbinview-builder

Conversation

@robert3005

Copy link
Copy Markdown
Contributor

Appending a VarBin array to a VarBinViewBuilder canonicalized it first. That built the views, wrapped them in a VarBinViewArray the builder immediately unwrapped, and then had append_varbinview_array rewrite every view to rebase its buffer index onto the builder's.

Number the buffer up front instead: varbin_decode_views takes the index the pushed buffer will land at, so the views come out already correct and the append is one view per row plus a buffer push. varbin_to_canonical now shares that helper, which also shrinks what match_each_integer_ptype! duplicates — the array construction no longer expands once per integer width.

A builder configured to compact still goes the canonical route. It chooses per buffer whether to keep, slice or rewrite it by measuring the finished views against the buffer, and push_buffer_and_adjusted_views takes buffers as they are, so the fast path would silently opt it out. VarBinViewBuilder::compacts_buffers is the new accessor that guards it.

Benchmarks

vortex-array/benches/chunk_array_builder.rs, fastest of 100 samples, 3 runs per side:

benchmark (rows × chunks) before after speedup
chunked_varbin_to_varbinview_builder 10×1000 313 µs 204 µs 1.53x
chunked_varbin_to_varbinview_builder 100×100 87.3 µs 69.5 µs 1.26x
chunked_varbin_to_varbinview_builder 1000×10 58.6 µs 54.8 µs 1.07x
chunked_varbin_opt_to_varbinview_builder 10×1000 378 µs 266 µs 1.42x
chunked_varbin_into_canonical 10×1000 357 µs 253 µs 1.41x

The last row is the control — it never touches the builder, so its gain comes from the shared-helper extraction alone. Relative to it, the append itself drops from 0.88x to 0.81x of a canonicalization. Most of the absolute win at high chunk counts is the smaller macro expansion; the rest is the skipped view rewrite.

Checks

  • cargo nextest run -p vortex-array -p vortex-fsst -p vortex-zstd -p vortex-onpair -p vortex-mask — 3377 passed
  • cargo clippy -p vortex-array --all-targets --all-features — clean
  • cargo +nightly fmt --all
  • New tests: append_varbin_to_varbinview_builder (interleaves VarBin appends with staged in-progress buffers and a VarBinView append, so buffer numbering is exercised) and append_varbin_to_a_compacting_builder_still_compacts.

🤖 Generated with Claude Code

@codspeed-hq

codspeed-hq Bot commented Jul 31, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 48.15%

❌ 6 regressed benchmarks
✅ 1836 untouched benchmarks
🆕 9 new benchmarks
⏩ 55 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation extend_from_array_non_zctl_overlapping[(10000, 8)] 713.2 µs 2,462.4 µs -71.03%
Simulation extend_from_array_non_zctl_overlapping[(1000, 32)] 298 µs 893.4 µs -66.64%
Simulation extend_from_array_zctl[(10000, 8)] 1.2 ms 2.2 ms -45.43%
Simulation extend_from_array_zctl[(1000, 64)] 734.9 µs 1,201 µs -38.81%
Simulation extend_from_array_non_zctl_overlapping[(1000, 8)] 301.3 µs 429.9 µs -29.93%
Simulation extend_from_array_zctl[(1000, 8)] 345.5 µs 402.1 µs -14.08%
🆕 Simulation chunked_varbin_into_canonical[(10, 1000)] N/A 2.5 ms N/A
🆕 Simulation chunked_varbin_into_canonical[(100, 100)] N/A 643.6 µs N/A
🆕 Simulation chunked_varbin_into_canonical[(1000, 10)] N/A 535.1 µs N/A
🆕 Simulation chunked_varbin_opt_to_varbinview_builder[(10, 1000)] N/A 2.8 ms N/A
🆕 Simulation chunked_varbin_opt_to_varbinview_builder[(100, 100)] N/A 663.5 µs N/A
🆕 Simulation chunked_varbin_opt_to_varbinview_builder[(1000, 10)] N/A 456.3 µs N/A
🆕 Simulation chunked_varbin_to_varbinview_builder[(10, 1000)] N/A 2.1 ms N/A
🆕 Simulation chunked_varbin_to_varbinview_builder[(100, 100)] N/A 592.5 µs N/A
🆕 Simulation chunked_varbin_to_varbinview_builder[(1000, 10)] N/A 520 µs N/A

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing rk/varbin-to-varbinview-builder (d4aaedf) with rk/onpair-decode-into-builder (8fa6c4f)

Open in CodSpeed

Footnotes

  1. 55 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Appending a `VarBin` array to a `VarBinViewBuilder` canonicalized it first, which
built the views, wrapped them in a `VarBinViewArray` the builder immediately
unwrapped, and then had `append_varbinview_array` rewrite every view to rebase
its buffer index onto the builder's.

Number the buffer up front instead: `varbin_decode_views` takes the index the
pushed buffer will land at, so the views come out already correct and the append
is one view per row plus a buffer push. `varbin_to_canonical` now shares that
helper, which also shrinks what `match_each_integer_ptype!` duplicates.

A builder configured to compact still goes the canonical route — it chooses per
buffer whether to keep, slice or rewrite it by measuring the finished views, and
`push_buffer_and_adjusted_views` would bypass that.

chunk_array_builder, fastest of 100 samples, 3 runs each:

| benchmark (rows x chunks)             | before  | after   | speedup |
| ------------------------------------- | ------- | ------- | ------- |
| varbin_to_varbinview_builder 10x1000  | 313 µs  | 204 µs  | 1.53x   |
| varbin_to_varbinview_builder 100x100  | 87.3 µs | 69.5 µs | 1.26x   |
| varbin_to_varbinview_builder 1000x10  | 58.6 µs | 54.8 µs | 1.07x   |
| varbin_opt_to_varbinview_bldr 10x1000 | 378 µs  | 266 µs  | 1.42x   |
| varbin_into_canonical 10x1000         | 357 µs  | 253 µs  | 1.41x   |

The last row is the control: it never touches the builder, so its gain is from
the shared-helper extraction alone. Relative to it, the append itself drops from
0.88x to 0.81x of a canonicalization.

Signed-off-by: Robert Kruszewski <github@robertk.io>
@robert3005
robert3005 force-pushed the rk/varbin-to-varbinview-builder branch from 30b5bcc to d4aaedf Compare August 1, 2026 10:30
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.

1 participant