Skip to content

Allow cross-crate inlining for BitSliceIterator - #10588

Open
connortsui20 wants to merge 1 commit into
apache:mainfrom
connortsui20:ct/inline-bitslice-iter
Open

Allow cross-crate inlining for BitSliceIterator#10588
connortsui20 wants to merge 1 commit into
apache:mainfrom
connortsui20:ct/inline-bitslice-iter

Conversation

@connortsui20

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

Downstream crates built without LTO cannot inline the BitSliceIterator hot path. This change also makes BitSliceIterator::next consistent with the annotated next implementations on BitIterator and BitIndexIterator.

Vortex discovered this gap while consuming arrow-buffer 58.4.0 from a separate crate.

What changes are included in this PR?

Adds #[inline] to BitSliceIterator::{new, advance_to_set_bit, next} and UnalignedBitChunk::iter.

Are these changes tested?

Yes.

Instruction-count measurements

Vortex's original arrow-buffer 58.4.0 experiment measured 13,729 marginal instructions per iteration unmodified and 8,565 with fat LTO and one codegen unit. Annotating only BitSliceIterator::next reduced the count to 13,151, while annotating the broader pre-bisection set reduced it to 10,026. The bisection on current main narrows that set to the four methods in this PR.

A local reproduction on current main measured the proposed change with a separate consumer crate:

Methods marked #[inline] Marginal instructions per iteration
None 15,028
Four methods in this change 7,584

Removing any one of the four attributes gives up part of the improvement:

Method without #[inline] Marginal instructions per iteration
BitSliceIterator::new 8,898
BitSliceIterator::advance_to_set_bit 14,015
BitSliceIterator::next 15,006
UnalignedBitChunk::iter 8,448

UnalignedBitChunk::new was also tested because it constructs this path. Adding it to the four-method set increases the result from 7,584 to 8,331 instructions, or 9.8%, so this PR does not annotate it.

The consumer iterates contiguous true runs over a 16,384-bit buffer at 1% density. It uses opt-level = 3, 16 codegen units, and no LTO. Callgrind counts from runs of 1,000 and 2,000 iterations were differenced to remove startup and setup instructions.

These are instruction counts, not wall-clock measurements.

On aarch64 macOS, the optimized arrow-buffer rlib changes from 1,799,592 to 1,808,184 bytes, an increase of 8,592 bytes or 0.48%. The median release compile time across five forced builds with warm dependencies remains 1.19 seconds.

Are there any user-facing changes?

No.

Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-buffer labels Aug 7, 2026

@Rich-T-kid Rich-T-kid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense to me

@alamb

alamb commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

looks good to me -- shall we perhaps add some comments explaining why the inline is needed in this case?

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

Labels

arrow Changes to the arrow crate arrow-buffer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow downstream crates to inline BitSliceIterator

3 participants