Skip to content

Performance improvements for MvccIterator#10

Open
mynameborat wants to merge 1 commit into
hkadayam:rust/mainfrom
mynameborat:performance-improvements
Open

Performance improvements for MvccIterator#10
mynameborat wants to merge 1 commit into
hkadayam:rust/mainfrom
mynameborat:performance-improvements

Conversation

@mynameborat
Copy link
Copy Markdown

@mynameborat mynameborat commented Mar 5, 2026

Performance improvements for MvccIterator

  1. into_results() on IndexQueryHandle — added to the trait and implemented in both SingleQueryHandle (moves out results from QueryResultHandle) and ShardedQueryHandle (moves out results vec). Used in iterators when !has_more() to avoid cloning the final batch.
  2. Reverse+pop pattern — both PlainRangeIterator and MvccRangeIterator now reverse batches on receipt and use pop() instead of remove(0). This changes batch draining from O(n^2) to O(n) per batch.
  3. Cached MvccQueryFilter Arc — the filter is created once in MvccRangeIterator::new() and reused via Arc::clone() in seek(), avoiding repeated Arc::new(MvccQueryFilter::new(...)) allocations.

Range Scan Benchmark Results

      ┌────────┬─────────┬─────────┬─────────────┬─────────────┐
      │  Keys  │ Before  │  After  │   Speedup   │ Throughput  │
      ├────────┼─────────┼─────────┼─────────────┼─────────────┤
      │ 10     │ 2.60 us │ 2.29 us │ 1.1x (-12%) │ 4.4 Melem/s │
      ├────────┼─────────┼─────────┼─────────────┼─────────────┤
      │ 100    │ 19.9 us │ 11.8 us │ 1.7x (-41%) │ 8.5 Melem/s │
      ├────────┼─────────┼─────────┼─────────────┼─────────────┤
      │ 1,000  │ 277 us  │ 148 us  │ 1.9x (-47%) │ 6.8 Melem/s │
      ├────────┼─────────┼─────────┼─────────────┼─────────────┤
      │ 5,000  │ 1.37 ms │ 771 us  │ 1.8x (-43%) │ 6.5 Melem/s │
      ├────────┼─────────┼─────────┼─────────────┼─────────────┤
      │ 10,000 │ 2.80 ms │ 1.56 ms │ 1.8x (-44%) │ 6.4 Melem/s │
      └────────┴─────────┴─────────┴─────────────┴─────────────┘```

 1. into_results() on IndexQueryHandle — added to the trait and implemented in both SingleQueryHandle (moves out results from QueryResultHandle) and ShardedQueryHandle (moves out results vec). Used in iterators when !has_more() to
 avoid cloning the final batch.
 2. Reverse+pop pattern — both PlainRangeIterator and MvccRangeIterator now reverse batches on receipt and use pop() instead of remove(0). This changes batch draining from O(n^2) to O(n) per batch.
 3. Cached MvccQueryFilter Arc — the filter is created once in MvccRangeIterator::new() and reused via Arc::clone() in seek(), avoiding repeated Arc::new(MvccQueryFilter::new(...)) allocations.

Range Scan Benchmark Results

 ┌────────┬─────────┬─────────┬─────────────┬─────────────┐
 │  Keys  │ Before  │  After  │   Speedup   │ Throughput  │
 ├────────┼─────────┼─────────┼─────────────┼─────────────┤
 │ 10     │ 2.60 us │ 2.29 us │ 1.1x (-12%) │ 4.4 Melem/s │
 ├────────┼─────────┼─────────┼─────────────┼─────────────┤
 │ 100    │ 19.9 us │ 11.8 us │ 1.7x (-41%) │ 8.5 Melem/s │
 ├────────┼─────────┼─────────┼─────────────┼─────────────┤
 │ 1,000  │ 277 us  │ 148 us  │ 1.9x (-47%) │ 6.8 Melem/s │
 ├────────┼─────────┼─────────┼─────────────┼─────────────┤
 │ 5,000  │ 1.37 ms │ 771 us  │ 1.8x (-43%) │ 6.5 Melem/s │
 ├────────┼─────────┼─────────┼─────────────┼─────────────┤
 │ 10,000 │ 2.80 ms │ 1.56 ms │ 1.8x (-44%) │ 6.4 Melem/s │
 └────────┴─────────┴─────────┴─────────────┴─────────────┘
@mynameborat mynameborat force-pushed the performance-improvements branch from f962d42 to c64d43c Compare March 5, 2026 02:38
@mynameborat mynameborat changed the title Fix RangeIterator O(n) drain and query_next_batch routing Performance improvements for MvccIterator Mar 5, 2026
if spec.mvcc_enabled {
config.merge_policy = MergePolicy::Never;
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I wouldn't want to merge this particular change and let it be in local changes as we should get to the bottom of NodeNotFound errors, the perf number wouldn't be representable with this issue

} else {
(handle.into_results(), None)
};
results.reverse();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I am not able to follow this change as well.

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.

2 participants