Skip to content

Conversation

@Zeutschler
Copy link

Summary

Add next_many(&mut self, dst: &mut [u32]) -> usize method to Iter and IntoIter for efficient batch extraction of bitmap values into a user-provided buffer.

Motivation

When iterating over large bitmaps, calling next() repeatedly incurs significant per-element overhead. The next_many() method extracts multiple values at once, enabling:

  • Reduced function call overhead
  • Better cache locality with contiguous buffer writes
  • ILP-friendly processing of batched results

This API mirrors the next_many() method available in CRoaring and the Go implementation of RoaringBitmap.

Performance

Benchmark next() next_many() Speedup
Dense (1M values, bitmap storage) 19.02ms 6.16ms 3.09x
Sparse (10K values, array storage) 1.67ms 159.58µs 10.46x

API

let mut iter = bitmap.iter();
let mut buf = [0u32; 1024];
loop {
    let count = iter.next_many(&mut buf);
    if count == 0 { break; }
    // Process buf[..count]
}

Returns the number of values written to dst. Returns 0 when the iterator is exhausted.

Implementation Details

  • Store::Iter: Direct slice copy for Array/Vec storage, bit extraction for Bitmap storage, run expansion for Interval stores
  • Container::Iter: Uses u16 buffer internally, combines with container key to produce u32 values
  • Bitmap::Iter/IntoIter: Handles front/back iterators from DoubleEndedIterator and container transitions

Checklist

  • Tests pass (cargo test)
  • No breaking changes
  • Backward compatible

Add next_many() method to RoaringBitmap iterators (both Iter and IntoIter)
for efficient batch extraction of values into a buffer.

This method is significantly faster than calling next() repeatedly:
- 2.5-3.1x speedup for dense bitmaps (bitmap storage)
- 10.5x speedup for sparse arrays (array storage)

Implementation details:
- Store::Iter: Direct slice copy for Array/Vec, bit extraction for Bitmap,
  run expansion for Interval stores
- Container::Iter: Uses u16 buffer internally, combines with container key
- Bitmap::Iter/IntoIter: Handles front/back iterators and container transitions

The API mirrors the next_many() method available in CRoaring and the Go
implementation of RoaringBitmap.

Benchmarks (1M dense values):
  next():      19.02ms
  next_many(): 6.16ms (3.09x faster)

Benchmarks (10K sparse values, every 100th):
  next():      1.67ms
  next_many(): 159.58µs (10.46x faster)
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