Repository navigation
Added bench - #3216
Open
fulmicoton wants to merge 1 commit into
Open
Added bench#3216fulmicoton wants to merge 1 commit into
fulmicoton wants to merge 1 commit into
Conversation
fulmicoton
force-pushed
the
paul.masurel/plain-codec-1-format-bench
branch
from
October 26, 2026 13:57
6fab651 to
7a9e9e0
Compare
fulmicoton
marked this pull request as ready for review
October 26, 2026 16:15
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Mallets
approved these changes
Oct 27, 2026
| pub fn open( | ||
| bytes: OwnedBytes, | ||
| num_values: u32, | ||
| dict_offsets_buffer: &mut Option<DictOffsetsBuffer>, |
Contributor
There was a problem hiding this comment.
nit: from an API point of view it's a bit weird to write &mut None.
I didn't check the feasibility but an alternative could be:
fn open(bytes: OwnedBytes, num_values: u32, dict_offsets_buffer: &mut Option<DictOffsetsBuffer>)and
fn recycle(self) -> Option<DictOffsetsBuffer>This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3179. Adds a benchmark for plain blocks, and uses it to make opening an OnPair16 block about 1.9x faster. Also makes the block index check added in #3179 vectorizable.
Benchmark
columnar/benches/bench_plain_block.rs(binggan), on the messages of the loghubApache_2k.logsample (2,000 values, 95,095 raw bytes, one 14,556-byte OnPair16 block). The data is incolumnar/benches/data/, with a README crediting loghub.It measures:
open_onpair16_block: opening a block, with a reused buffer (whatPlainValueReaderdoes);open_onpair16_block_fresh_buffer: opening a block with a new buffer (the first block of a reader);read_all_values: reading the 2,000 values of an open block;open_and_read_one_value: a point lookup.PlainBlock,DictOffsetsBufferandencode_plain_blockare exported as#[doc(hidden)]for the benchmark: they are not part of the stable API.Faster block open
Opening a block dominates point lookups: on
mainit takes ~416 ns, while reading one value of an open block takes ~15 ns. On the benchmark block (mainmeasured with the same benchmark, adapted to its API):main(#3179)open_onpair16_block)open_onpair16_block_fresh_buffer)open_and_read_one_value)read_all_values)On
main, every block open allocates its dict offsets, so both open rows are the same.The changes:
BitPacker4x::compress_strictly_sortedon 4 bits, in chunks of 128, and decoded with SIMD unpacking and prefix sum. A 4-bit delta always decodes to a token length in 1..=16, even on corrupted data. It takes 64 bytes per 128 tokens, as before, but the last chunk is padded with zero deltas: up to 63 more bytes per block when the dictionary is not a multiple of 128 tokens (36 bytes on the benchmark block).CompactDictionaryView::validate_safety, only the read padding of the last token is not guaranteed by construction (at most 2^12 tokens,dict_offsets[0] == 0, token lengths in 1..=16).opennow checks only that, and runsvalidate_safetyin adebug_assert.DictOffsetsBuffer(Box<[u32; 2^12 + 1]>, 16 KiB), sized for the largest dictionary (MAX_CODE_BITS = 12).PlainBlock::opentakes it,PlainBlock::recyclegives it back, andPlainValueReaderkeeps it from block to block, so a reader only allocates it for its first block.Reading the values of an open block is unchanged.
The format change is safe: the plain format of #3179 is not released yet, and the columnar writer does not produce plain columns yet.
Faster block index check
#3179 checks at column open that the value starts and byte starts of the block index are strictly increasing. The check looped over the entries with an early exit and a short-circuit
||, which prevents vectorization. It is now one branch-free fold per array (is_strictly_increasing, over a cloneable iterator), optimized for valid indexes:The check only runs when a column is opened, so this does not show in
bench_plain_block. An invalid index is still rejected, with the same error, after the full pass.🤖 Generated with Claude Code